嵌套异步db调用for循环,等待循环完成

时间:2016-11-16 16:21:08

标签: javascript mongodb express

我在mongodb中使用listCollection方法,并使用find使用查询循环遍历每个返回的集合。

问题是我使用循环来构造一个对象,我希望在循环结束后用response.json返回但由于find是异步的,我不知道如何“等待”在返回find

之前,每个response.json()回调都已完成
var data = {};

database.listCollections({name: {$ne: 'system.indexes'}}).toArray(function(err, collections) {
    if (err) return res.json({});

    for(i=0; i<collections.length; i++){
        var collection = collections[i].name;

        database.collection(collection).find(query, limit)
        .sort({"Date": -1}).toArray(function(err, docs){

            if (err) return res.json({
            });

               /* Do stuff with docs, push stuff to data */
        });
        /** Console shows blank **/
        console.log("Data " + i+ ": " + JSON.stringify(data));
    }
  /** Response is blank.. **/
  res.json(data);
});

问题是for循环在find()完成之前返回方式。如何以JS / Node方式处理此问题?我可以破解一个解决方案,但我可能会在以后遇到类似的问题..

编辑:我确信数据实际上已被正确地返回和处理,因为每个数据查找中的console.log()表明它实际上有内容。

1 个答案:

答案 0 :(得分:1)

如果您的NodeJS版本支持它,您可以使用Promise,否则使用任何Promise库。在这种情况下,您可以将for循环中的代码包装到返回Promise的某个函数中,然后将所有这些promises对象推送到数组中。循环调用后

Promise.all(promisesArray).then(/* Callback function that sends response */)

另一种选择是使用递归而不是for循环并在达到停止条件时发送请求。但我认为这不是一个好选择,因为如果collections数组很大,你可以超过最大堆栈大小。