node.js嵌套回调,获取最终结果数组

时间:2014-03-06 01:37:26

标签: javascript node.js mongodb

我正在做一个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);
        }
    })
});

2 个答案:

答案 0 :(得分:1)

虽然我并不完全熟悉MongoDB,但快速阅读他们的documentation表明他们提供了 异步 Node.js界面。

也就是说,findOnefind操作都会启动,但是当您达到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的最后一个参数。