2016-03-05 58 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

(顺便说一句,我认为你应该使用更像“改进独立嵌套异步调用”的方式重命名您的问题,以避免发生关闭/重复问题。)