2016-03-05 91 views
2

我有以下代碼的NodeJS:在nodejs中回調內部回調?

app.get('/dashboard', function(req, res){ 

    db.collection('com_url_mamy').find().toArray(function(err, doc){ 
     db.collection('com_url_mamy').find({'price':''}).count(function(err, docs){ 
     db.collection('com_url_mamy').find({"price":{$not:{$ne:"last_price_1"}}}).count(function(err, last_doc){ 

     if(err){console.log(err);} 
     console.log(docs); 
     res.render('dashboard',{'doc':doc, 'docs':docs, 'last_doc':last_doc}); 
    }); 
    }); 
    }); 

在這裏,我要添加更多的兩個或三個查詢/回調。

但我不認爲這是正確的做法。 請任何人都可以告訴我如何解決此問題以提高性能。

謝謝

+2

@MehdiElFadil這不是重複的。他可以使用Promises和多個併發異步調用來改善他的代碼。您鏈接的問題是關於代碼風格,而他的問題是關於特定情況下的性能問題,而不是可以改進的問題。 –

+1

我在這裏貼了我的答案,因爲問題已經無故關閉http://paste.ofcode.org/zHmnq2u8qKzDx9ggnYHep9 由於你的3個查詢不依賴於其他人,你可以使用'''Promise.all'''並行執行其中的3個。 –

+2

順便說一句'''{price「:{$ not:{$ ne:」last_price_1「}}}'''可以重構爲'''{」price「:」last_price_1「}''(不等於等於:p) –

回答

4

可以使用async libary尤其是async.parallel()方法時,你需要運行不依賴於彼此的多個任務,當他們都完成做別的事情。

請看下面的例子:

app.get('/user/:name', function(req, res, next) { 
    var locals = {}; 
    async.parallel([ 

     // Load all documents 
     function(callback) { 
      db.collection('com_url_mamy').find().toArray(function(err, docs){ 
       if (err) return callback(err); 
       locals.docs = docs; 
       callback(); 
      }); 
     }, 

     // Get count of documents where price is empty 
     function(callback) { 
      db.collection('com_url_mamy').find({'price':''}).count(function(err, count){ 
       if (err) return callback(err); 
       locals.count = count; 
       callback(); 
      }); 
     }, 

     // Load last docs 
     function(callback) { 
      db.collection('com_url_mamy').find({"price": "last_price_1"}).count(function(err, docs){ 
       if (err) return callback(err); 
       locals.last_doc = docs; 
       callback(); 
      }); 
     } 
    ], function(err) { //This function gets called after the three tasks have called their "task callbacks" 
     if (err) return next(err); 
     //Here render dashboard with locals object 
     res.render('dashboard', locals); 
    }); 
}); 
3

您可以使用MongoDB的原生驅動的承諾(在node.js的> = 0.12):

app.get('/dashboard', function(req, res){ 
    var proms = []; 

    proms.push(db.collection('com_url_mamy').find().toArray()); 
    proms.push(db.collection('com_url_mamy').find({'price':''}).count()); 
    proms.push(db.collection('com_url_mamy').find({"price": "last_price_1"}).count()); 

    Promise.all(proms) 
    .then(function(pres) { 
    res.render('dashboard',{'doc':pres[0], 'docs': pres[1], 'last_doc': pres[2]}); 
    }) 
    .catch(console.error); 
}); 

Promise.all需要你給它的承諾和執行他們並行。

的Promise.all(迭代器)方法返回解析當所有的迭代器參數的承諾已經解決了一個承諾

來源: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

(順便說一句,我認爲你應該使用更像「改進獨立嵌套異步調用」的方式重命名您的問題,以避免發生關閉/重複問題。)