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多行的代碼,就精簡到了十多行,而且封裝的函數能夠在不少地方使用。

相關文章
相關標籤/搜索