node——含有异步函数的函数封装

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

以前写的新闻代码中,常常出现的操做有对文件的读取,咱们能够将它封装为一个函数readNewsData()json

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

在引用的时候:原代码post

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)url

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

原代码:

 

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多行的代码,就精简到了十多行,而且封装的函数能够在不少地方使用。

相关文章
相关标签/搜索