• node——模块化


    之前写的新闻部分几乎所有操作都写在了一起,这次开始进行模块化。

    为什么要模块化:

    1.提高开发效率,所有操作在一个文件内,不方便团队操作,模块化可多人同时操作

    2.当程序出错,可以分模块寻找错误

    3.可以使程序不一次性全部展示出来,保留一些操作不可见

    模块化步骤:

    1.思考,该模块中要封装什么代码?

    2.思考,这些代码有用到什么外部数据?如果用到了该如何传递
    3.当前模块对外需要暴露的东西(moudule.eports的值)

    原代码:

    var http=require('http');
    var fs=require('fs');
    var path=require('path');
    var mime=require('mime');
    var url=require('url');
    var querystring=require('querystring');
    var _=require('underscore');
    
    http.createServer(function(req,res){
    
    res.render=function(filename,tqData){
        fs.readFile(filename,function(err,data){
            if(err)
            {
                res.writeHead(404,'Not Found',{'Content-Type':'text/html;charset=utf-8'});
                res.end('44,not found');
                return;
            }
            if(tqData){
                var fn=_.template(data.toString('utf8'));
                data=fn(tqData);
    
            }
            res.end(data);
        })
    
    }
    
    
    
    req.url=req.url.toLowerCase();
    req.method=req.method.toLowerCase();
    
    var urlObj=url.parse(req.url,true);
    
    if(req.url==='/'||req.url==='/index'&&req.method==='get')
    {
        readNewsData(function(list){
            res.render(path.join(__dirname,'views','home.html'),{list:list});
        })
    
    }else if(req.url==='/submit'&&req.method==='get'){
    
        res.render(path.join(__dirname,'views','submit.html'));
            
    }else if(urlObj.pathname==='/item'&&req.method==='get'){
    
    readNewsData(function(list){
    
            for(var i=0;i<list.length;i++)
            {
    
                if(list[i].id.toString()===urlObj.query.id)
                {
                    model=list[i];
                    break;
    
                }
            }
            if(model)
            {
                res.render(path.join(__dirname,'views','details.html'),{item:model});
            }
            else
            {
                res.end('no found')
            }
        })
    
    }else if(req.url.startsWith('/add')&&req.method==='get'){
    
        fs.readFile(path.join(__dirname,'data','data1.json'),'utf8',function(err,data){
            if(err&&err.code!=='ENOENT'){
                throw err;
            }
            var list_news=JSON.parse(data||'[]');
            
        });
    
        
        
            
    }else if(req.url.startsWith('/add')&&req.method==='post'){
            
            readNewsData(function(list_news){
                
                postBodyData(req,function(postBody){
                
                postBody.id=list_news.length;
                list_news.push(postBody);
                
                writeNewsData(JSON.stringify(list_news),function(){
                res.statusCode=302;
                res.statusMessage='Found';
                res.setHeader('Location','/');
                res.end('over');
    
                    });
            });
        });
    
        
    }else if(req.url.startsWith('/resource')&&req.method==='get'){
    
    
        res.render(path.join(__dirname,req.url));
    
    }        
    else{
        res.writeHead(404,'NOT FOUND',{
            'Content-Type':'text/plain;charset=utf-8'
        });
        res.end('404,page not found');
    }
    }).listen(9090,function(){
        console.log('http://localhost:9090');
    })
    
    
    function readNewsData(callback){
        fs.readFile(path.join(__dirname,'data','data1.json'),'utf8',function(err,data){
            if(err&&err.code!=='ENOENT'){
                throw err;
            }
    
            var list_news=JSON.parse(data||'[]');
            //通过回调函数callback()将读取到的数据list,传递出去
            callback(list_news);
        });
    }
    
    
    function writeNewsData(data,callback){
        fs.writeFile(path.join(__dirname,'data','data1.json'),data,function(err){
            if(err){
                throw err;
            }
            console.log('ok');
        });
    
            callback();
    }
    
    
    function postBodyData(req,callback){
        
                var array=[];
            req.on('data',function(chunk){
                array.push(chunk);
        
            });
    
            req.on('end',function(){
                var postBody=Buffer.concat(array);
                postBody=postBody.toString('utf8');
                
                postBody=querystring.parse(postBody);
            
            callback(postBody);
            });
    }
    View Code

    模块化部分:

    模块一(服务模块):负责启动服务
    模块二(扩展模块):负责扩展req和res对象,为res和res对象,为req和res增加以下更方便更好用的API
    模块三(路由模块):负责路由判断
    模块四(业务模块):负责处理具体路由的业务的代码

    模块一(index.js)

    代码:

     1 var http=require('http');
     2 var context=require('./context.js');
     3 var router=require('./router.js');
     4 var handler=require('./handler.js');
     5 
     6 http.createServer(function(req,res){
     7     //调用context.js模块的返回值(函数),并将req和res对象传递给context.js模块
     8     context(req,res);
     9     //调用路由模块返回值
    10     router(req,res);
    11 
    12 
    13 }).listen(9090,function(){
    14     console.log('http://localhost:9090');
    15 })
    View Code

    模块二(context.js)

    负责扩展req和res对象,为res和res对象,为req和res增加以下更方便更好用的API
    希望在该模块做:
    1.为req增加一个query熟悉,该属性中保存的就是用户get请求提交过来的数据
    -req.query
    2.为req增加一个pathname属性
    -req.pathname
    3.为res增加一个render函数

    代码:

    var http=require('http');
    var fs=require('fs');
    var path=require('path');
    var mime=require('mime');
    var url=require('url');
    var querystring=require('querystring');
    var _=require('underscore');
    
    //让当前模块对外暴露一个函数,通过这个函数将res,req传入模块中
    module.exports=function(req,res){
    
        //1.为req增加query属性
        var urlObj=url.parse(req.url.toLowerCase(),true);
        req.query=urlObj.query;
        //2.为req增加pathname属性
        req.pathname=urlObj.pathname;
        //3.为req增加method属性
        req.method=req.method.toLowerCase();
    
        //3.为res增加函数
        res.render=function(filename,tqData){
            fs.readFile(filename,function(err,data){
                if(err)
                {
                    res.writeHead(404,'Not Found',{'Content-Type':'text/html;charset=utf-8'});
                    res.end('44,not found');
                    return;
                }
                if(tqData){
                    var fn=_.template(data.toString('utf8'));
                    data=fn(tqData);
    
                }
                res.end(data);
            });
        };
    
    };
    View Code

    模块三(router.js)

    该模块负责封装所以路由判断代码

    代码:

     1 //该模块负责封装所以路由判断代码
     2 
     3 var handler=require('./handler');
     4 
     5 
     6 module.exports = function(req,res){
     7     if(req.url==='/'||req.url==='/index'&&req.method==='get')
     8 {
     9     handler.index(req,res);
    10 
    11 }else if(req.pathname==='/submit'&&req.method==='get'){
    12     handler.submit(req,res);
    13         
    14 }else if(req.pathname==='/item'&&req.method==='get'){
    15     handler.item(req,res);
    16 
    17 }else if(req.url.startsWith('/add')&&req.method==='post'){
    18     handler.add(req,res);
    19     
    20 }else if(req.url.startsWith('/resource')&&req.method==='get'){
    21     handler.resource(req,res);
    22 
    23 }        
    24 else{
    25     handler.nofound(req,res);
    26 }
    27 }
    View Code

    模块四(handler.js)

    该模块负责对具体的业务进行处理

    代码:

      1 //该模块负责对具体的业务进行处理
      2 var path=require('path');
      3 var fs=require('fs'); 
      4 var querystring=require('querystring');
      5 
      6 module.exports.index=function(req,res){
      7     if(req.pathname==='/'||req.url==='/index'&&req.method==='get')
      8     {
      9     readNewsData(function(list){
     10         res.render(path.join(__dirname,'views','home.html'),{list:list});
     11     })
     12 }}
     13 
     14 module.exports.submit=function(req,res){
     15     res.render(path.join(__dirname,'views','submit.html'));
     16 }
     17 
     18 module.exports.item=function(req,res){
     19     readNewsData(function(list){
     20 
     21         for(var i=0;i<list.length;i++)
     22         {
     23 
     24             if(list[i].id.toString()===req.query.id)
     25             {
     26                 model=list[i];
     27                 break;
     28 
     29             }
     30         }
     31         if(model)
     32         {
     33             res.render(path.join(__dirname,'views','details.html'),{item:model});
     34         }
     35         else
     36         {
     37             res.end('no found')
     38         }
     39     })
     40 
     41 }
     42 
     43 
     44 module.exports.add=function(req,res){
     45     //1.读取data1.json
     46         readNewsData(function(list_news){
     47             //2.读取用户post提交的数据
     48             postBodyData(req,function(postBody){
     49             //3.为用户提交的新闻增加一个id属性,并且把新闻对象push到list中
     50             postBody.id=list_news.length;
     51             list_news.push(postBody);
     52             //将list数组写入到data1.json中
     53             writeNewsData(JSON.stringify(list_news),function(){
     54             res.statusCode=302;
     55             res.statusMessage='Found';
     56             res.setHeader('Location','/');
     57             res.end('over');
     58 
     59                 });
     60         });
     61     });
     62 
     63 }
     64 
     65 
     66 module.exports.resource=function(req,res){
     67     res.render(path.join(__dirname,req.pathname));
     68 }
     69 
     70 
     71 module.exports.nofound=function(req,res){
     72     res.writeHead(404,'NOT FOUND',{
     73         'Content-Type':'text/plain;charset=utf-8'
     74     });
     75     res.end('404,page not found');
     76 }
     77 
     78 
     79 function readNewsData(callback){
     80     fs.readFile(path.join(__dirname,'data','data1.json'),'utf8',function(err,data){
     81         if(err&&err.code!=='ENOENT'){
     82             throw err;
     83         }
     84 
     85         var list_news=JSON.parse(data||'[]');
     86         //通过回调函数callback()将读取到的数据list,传递出去
     87         callback(list_news);
     88     });
     89 }
     90 
     91 function writeNewsData(data,callback){
     92     fs.writeFile(path.join(__dirname,'data','data1.json'),data,function(err){
     93         if(err){
     94             throw err;
     95         }
     96         console.log('ok');
     97     });
     98 
     99         //这里写当写入数据完毕后的操作
    100         callback();
    101 }
    102 
    103 function postBodyData(req,callback){
    104     
    105         var array=[];
    106         req.on('data',function(chunk){
    107             array.push(chunk);
    108             //
    109         });
    110 
    111         req.on('end',function(){
    112             var postBody=Buffer.concat(array);
    113             postBody=postBody.toString('utf8');
    114             
    115             postBody=querystring.parse(postBody);
    116         
    117             callback(postBody);
    118         });
    119 }
    View Code

    执行顺序

    index.js文件从上往下执行,先加载context,在加载router,由于router文件内要先加载handler,所以handler顺序比router前面点,之后就开始监听9090端口,当有了请求后就执行http内部的代码了。

     

  • 相关阅读:
    [POJ1195] Mobile phones(二维树状数组)
    [SWUST1740] 圆桌问题(最大流)
    [SWUST1759] 骑士共存问题(最大流,最大独立集)
    欧拉函数O(sqrt(n))与欧拉线性筛素数O(n)总结
    BZOJ 1036: [ZJOI2008]树的统计Count-树链剖分(点权)(单点更新、路径节点最值、路径求和)模板,超级认真写了注释啊啊啊
    POJ 3237.Tree -树链剖分(边权)(边值更新、路径边权最值、区间标记)贴个板子备忘
    计蒜客 30999.Sum-筛无平方因数的数 (ACM-ICPC 2018 南京赛区网络预赛 J)
    洛谷 P3383 【模板】线性筛素数-线性筛素数(欧拉筛素数)O(n)基础题贴个板子备忘
    计蒜客 30996.Lpl and Energy-saving Lamps-线段树(区间满足条件最靠左的值) (ACM-ICPC 2018 南京赛区网络预赛 G)
    计蒜客 30990.An Olympian Math Problem-数学公式题 (ACM-ICPC 2018 南京赛区网络预赛 A)
  • 原文地址:https://www.cnblogs.com/ellen-mylife/p/11004837.html
Copyright © 2020-2023  润新知