[英]node.js nested callback, get final results array
我正在做一个for循环,从mongodb中查找结果,并连接该数组。 但是循环完成后,我没有得到最终结果数组。 我是node.js的新手,我认为它不像Objective-C回调那样工作。
app.get('/users/self/feed', function(req, res){
var query = Bill.find({user: req.param('userId')});
query.sort('-createdAt');
query.exec(function(err, bill){
if (bill) {
var arr = bill;
Following.findOne({user: req.param('userId')}, function(err, follow){
if (follow) {
var follows = follow.following; //this is a array of user ids
for (var i = 0; i < follows.length; i++) {
var followId = follows[i];
Bill.find({user: followId}, function(err, result){
arr = arr.concat(result);
// res.send(200, arr);// this is working.
});
}
} else {
res.send(400, err);
}
});
res.send(200, arr); //if put here, i am not getting the final results
} else {
res.send(400, err);
}
})
});
虽然我对MongoDB并不十分熟悉,但快速阅读它们的文档显示它们提供了一个异步 Node.js接口。
就是说, findOne
和find
操作都开始,但是不一定要在到达res.send(200, arr)
时完成,这意味着arr
仍然为空。
相反,一旦所有异步调用完成,您应该将响应发送回去, 这意味着您可以执行以下操作:
var billsToFind = follows.length;
for (var i = 0; i < follows.length; i++) {
var followId = follows[i];
Bill.find({user: followId}, function(err, result){
arr = arr.concat(result);
billsToFind -= 1;
if(billsToFind === 0){
res.send(200, arr);
}
});
}
该方法对所有内部异步调用都使用一个计数器(我忽略了findOne
因为无论如何我们目前都在其回调中)。 由于每个Bill.find
调用完成它递减计数器,一旦它到达0它意味着所有的回调已经解雇(这工作,因为Bill.find
被要求在每个数组项follows
),并把它发送回来的全阵列响应。
确实如此。 你的代码里面for
将并行同时执行(与相同的值i
我认为)。 如果在console.log
内添加了console.log
,并且在for
循环之后for
您会发现外侧一号先于内侧一号打印。
您可以将for
内部的代码包装到函数数组中,并使用async
模块( https://www.npmjs.org/package/async )并行或串行执行它们,然后从async.parallel
或async.series
的最后一个参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.