zoukankan      html  css  js  c++  java
  • node——含有异步函数的函数封装

    在写代码时我们会发现有大量的重复代码,为了使代码更加简洁,我们可以将重复的代码封装为一个可以在多个部分时候用的函数。

    之前写的新闻代码中,经常出现的操作有对文件的读取,我们可以将它封装为一个函数readNewsData()

    function readNewsData(){
        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||'[]');
            //return list;//在这样返回值是不正确的,这里返回的值是fs.readfile返回的值,不是readNewsData函数返回的值
            
        });
        return list;
    
    }

    在读取文件后返回list,但是因为有fs.readFile,fs.readFile有异步回调

    当执行readNewsData函数时,先开启fs.readfile(),在开启后立即执行下面的return list;根本不会等fs.readfile将文件读完。

    所以对于有异步回调的和函数,我们不能以return的形式返回值

    所以:通过回调函数callback()将读取到的数据list,传递出去

    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);
        });
    }

    在引用的时候:原代码

    else if(urlObj.pathname==='/item'&&req.method==='get'){
    
    
        fs.readFile(path.join(__dirname,'data','data1.json'),'utf8',function(err,data){
        
            if(err&&err.code!=='ENOENT'){
                
                throw err;
            }
            var model=null;
    
            var list_news=JSON.parse(data||'[]');
    
            for(var i=0;i<list_news.length;i++)
            {
    
                if(list_news[i].id.toString()===urlObj.query.id)
                {
                    model=list_news[i];
                    break;
    
                }
            }
            if(model)
            {
                res.render(path.join(__dirname,'views','details.html'),{item:model});
            }
            else
            {
                res.end('no found')
            }
            
        });
        

    现在:

    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')
            }
        })
    
    }

    这样代码会少一些,而readNewsData(function(list){});里面的list就是封装函数里面callback(list)

    写入文件函数和上面的方法一样

    原代码:

    else if(req.url.startsWith('/add')&&req.method==='post'){
    fs.readFile(path.join(__dirname,'data','data1.json'),'utf8',function(err,data){
            //因为第一次访问网站,data1.json文件本身就不存在,所以会有异常
            //这种错误,我们不认为是网站出错了,所以不需要抛出异常
            if(err&&err.code!=='ENOENT'){
                throw err;
            }
            //如果data没有读取到,则data为空,转换为数组
            var list_news=JSON.parse(data||'[]');
    
            
            var array=[];
            req.on('data',function(chunk){
                //此处的chunk参数,就是浏览器本次提交过来的一部分数据
                //chunk的数据类型是buffer
                array.push(chunk);
        
            });
    
            //监听request对象的end事件
            //当end事件被触发时,数据提交完成
            req.on('end',function(){
                var postBody=Buffer.concat(array);
                postBody=postBody.toString('utf8');
                
                postBody=querystring.parse(postBody);
            
                //把新闻添加到list之前,为新闻增加一个id
                postBody.id=list_news.length;
    
                //将用户的push提交到新闻push到List_news中
                list_news.push(postBody);
                fs.writeFile(path.join(__dirname,'data','data1.json'),JSON.stringify(list_news),function(err){
            if(err){
                throw err;
            }
            console.log('ok');
        });
    
                res.statusCode=302;//跳转
        res.statusMessage='Found';
        res.setHeader('Location','/');
                res.end('over');
            });
            
        });
        
    }

    红色部分封装代码

    //封装一个写入data1.json的函数
    //这里传过来的data是转换为字符串的数据
    function writeNewsData(data,callback){
        fs.writeFile(path.join(__dirname,'data','data1.json'),data,function(err){
            if(err){
                throw err;
            }
            console.log('ok');
        });
    
            //这里写当写入数据完毕后的操作
            callback();
    }

    修改后:

    else if(req.url.startsWith('/add')&&req.method==='post'){
        readNewsData(function(list_news){
                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);
            
                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');
    
                });
            
            });
    
        });
    
        
    }

     上面post提交数据还可以封装为一个函数

    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);
            //把用户post提交过来的返回
            callback(postBody);
            });
    }

    原来post函数修改后

    else if(req.url.startsWith('/add')&&req.method==='post'){
            //1.读取data1.json
            readNewsData(function(list_news){
                //2.读取用户post提交的数据
                postBodyData(req,function(postBody){
                //3.为用户提交的新闻增加一个id属性,并且把新闻对象push到list中
                postBody.id=list_news.length;
                list_news.push(postBody);
                //将list数组写入到data1.json中
                writeNewsData(JSON.stringify(list_news),function(){
                res.statusCode=302;
                res.statusMessage='Found';
                res.setHeader('Location','/');
                res.end('over');
    
                    });
            });
        });
    
        
    }

    这样原来有20多行的代码,就精简到了十多行,并且封装的函数可以在很多地方使用。

  • 相关阅读:
    jQuery选择器支持正则匹配
    js监听dom元素内容变化
    icon
    arclist 分页
    dede 手机模板 上一篇下一篇 链接错误问题解决办法
    css解决移动端 文字垂直居中问题
    网页即时QQ聊天
    apache ,ip访问的默认页
    swiper初始化
    JQ锚点,平滑滚动
  • 原文地址:https://www.cnblogs.com/ellen-mylife/p/10965071.html
Copyright © 2011-2022 走看看