我正在做一个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);
}
})
});
答案 0 :(得分:1)
虽然我并不完全熟悉MongoDB,但快速阅读他们的documentation表明他们提供了 异步 Node.js界面。
也就是说,findOne
和find
操作都会启动,但是当您达到res.send(200, arr)
意味着arr
将仍然<时,不一定完成/ em>是空的。
相反,您应该在 所有 异步调用完成后发回您的响应,这意味着您可以执行以下操作:
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
所以这是有效的使用完整数组发回响应。
答案 1 :(得分:0)
这是真的。 for
中的代码将同时并行执行(我认为i
的值相同)。如果您在console.log
循环内部和之后添加了for
,则会发现外部的内容将在内部之前打印出来。
您可以将for
内的代码包装到函数数组中,并使用async
模块(https://www.npmjs.org/package/async)并行或串行执行它们,并从async.parallel
中检索最终结果{1}}或async.series
的最后一个参数。