Mongodb使用promises以同步方式迭代集合

时间:2016-04-20 12:00:03

标签: node.js mongodb promise bluebird

我有一个方法(参见代码示例),我试图将promises列表返回给父方法。我的问题是在我的promiseList数组中推送promises。

getDistance 是一个返回Promise的方法。如果我在getDistance方法中执行 .then(),一切正常。尽管如此,如果我尝试将promise转移到我的数组中,那么当我执行时。然后在父方法中,它是空的。

我认为这可能是由于每个循环都是异步的......

var promiseList = [];
    res = db.collection.find query statement... 
    res.each(function(err, doc) {
        if (doc!==null) {
            promiseList.push(
                 getDistance(orgLat, orgLon, destLat, desLon)
            );
        }
    });
    return Promise.all(promTimeList);

我使用MongoDB作为数据库,在服务器端使用NodeJS,mongodb作为驱动程序连接到我的数据库,Bluebird作为库来实现promises。

提前致谢!

2 个答案:

答案 0 :(得分:1)

我认为你的问题是正确的,因为each是异步的。您可以使用defer将回调API(如each)包装到promises中。它可以这样工作:

res = db.collection.find query statement... 
processResponse(res)
    .then(function(promiseList) {
        // execute all the promises
        return Promise.all(promiseList);
    }, function (err) {
        // handle error
    });    

function processResponse(res) {
    var deferred = Promise.pending();
    var promiseList = [];
    res.each(function(err, doc) {
        if (err) {
            // error, abort
            deferred.reject(err);
            return;
        }
        else if (doc != null) {
            promiseList.push(
                getDistance(orgLat, orgLon, destLat, desLon)
            );
        }
        else {
           // finished looping through all results, return the promise list
           deferred.resolve(promiseList);
        }
    });
    return deferred.promise;
}

在以下链接中查看有关蓝鸟的defer的更多信息(查找“那么应该延迟使用什么时候?”):

IEEE Std 1800-2012

更新:根据这篇文章:

https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns

看起来有一个Promise构造函数可能是执行此操作的首选方法。 processResponse方法如下所示:

function processResponse(res) {
    return new Promise(function(resolve, reject) {
        var promiseList = [];
        res.each(function(err, doc) {
            if (err) {
                // error, abort
                reject(err);
                return;
            }
            else if (doc != null) {
                promiseList.push(
                    getDistance(orgLat, orgLon, destLat, desLon)
                );
            }
            else {
               // finished looping through all results, return the promise list
               resolve(promiseList);
            }
        });
    });
}

感谢@Bergi。如果我错了,请纠正我。我对Q库(Define empty Bluebird promise like in Q)比蓝鸟更熟悉。

答案 1 :(得分:1)

Row { anchors.fill: parent Flickable { width: parent.width * .5 height: parent.height flickableDirection: Flickable.VerticalFlick contentHeight: contentItem.childrenRect.height Column { spacing: 2 Repeater { model: 5 delegate: Rectangle { width: 100; height: 100; color: "red" } } Repeater { model: 5 delegate: Rectangle { width: 100; height: 100; color: "green" } } Repeater { model: 5 delegate: Rectangle { width: 100; height: 100; color: "blue" } } } } Column { width: parent.width * .5 height: parent.height spacing: 2 ListView { spacing: 2 width: parent.width height: parent.height / 3 model: 5 clip: true delegate: Rectangle { width: 100; height: 100; color: "red" } } ListView { spacing: 2 width: parent.width height: parent.height / 3 model: 5 clip: true delegate: Rectangle { width: 100; height: 100; color: "green" } } ListView { spacing: 2 width: parent.width height: parent.height / 3 model: 5 clip: true delegate: Rectangle { width: 100; height: 100; color: "blue" } } } } 循环中使用awaitcursor.next()同步迭代集合:

while