我有以下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});
});
});
});
在这里,我必须添加更多两个或三个查询/回调。
但我不认为这是正确的做法。 请任何人告诉我如何解决这个问题以提高性能。
谢谢
答案 0 :(得分:4)
在这种情况下,使用async / await将是一个合适的解决方案,可以避免回调地狱。考虑按如下方式运行查询:
app.get('/user/:name', async (req, res, next) => {
try {
const docs = await db.collection('com_url_mamy').find().toArray()
const count = await db.collection('com_url_mamy').find({'price':''}).count()
const last_doc = await db.collection('com_url_mamy').find({"price": "last_price_1"}).count()
res.render('dashboard', { docs, count, last_doc })
} catch (err) {
return next(err)
}
}
作为替代方案,当您需要运行多个不依赖的任务时,您可以使用 async 库,尤其是 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);
});
});
答案 1 :(得分:3)
您可以将本机Promise与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(iterable)方法返回一个promise,它在iterable参数中的所有promise都已解析时解析
来源: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
(顺便说一下,我认为你应该用更多类似'改进独立嵌套异步调用'的方式重命名你的问题,以避免你的关闭/重复问题。)