如何处理mongodb cursor.each中的longs动作?

时间:2016-11-23 10:47:00

标签: node.js mongodb

我有一个.each()循环和每个循环中更新的全局变量。在每个循环中都有一个collection.find,并且node.js不等待搜索完成并转到下一个元素,然后find甚至得到第一个结果,并且'有问题。我不认为让它等待是正确的做法,我想处理它"节点方式" (告诉我,如果我不应该)

以下是我的代码的简化版本:

(它会找到所有50年前的客户,并对他们所在城市的商店做点什么)

var clients = db.collection('clients');
var current;
var clientnumber=0;

clients.find({"age":50},function(err,results){
    results.each(function(err,client){
        if(client){
            clientnumber++;
            var city = client.city;
            shops.find({"_id":city},function(err,resCursor){
                resCursor.toArray(function(err,bson){
                    //does stuff using the city, client number variables and data from "shop"
                    //including another find and each operation
                });
            });
            clientnumber++;
        }
    }
});

clientnumber不是id,只计算有多少50岁的客户)

当我运行此代码时,each循环对于find来说太快了,因此clientnumbercity等变量在{findcities[clientnumber]=city时不是最新的调用1}}回调。我该怎么办?

我在考虑为城市添加数组,例如clientnumer,但我不知道如何跟踪var currentcity=city;。我认为在本地传递变量,比如connection.createStatement().execute("SHUTDOWN"); ,但我不能确定它会在下一个客户端之前完成,我不想为每个客户做这件事。嵌套。

如何跟踪我的全局变量?您可以对结构进行评论,但它非常简化,因此可能不适用。

1 个答案:

答案 0 :(得分:0)

按顺序循环遍历客户端。在开始下一个之前等待每个结束。

clients.find({"age":50},function(err,results){
    doclient(clientnumber, 0, results.length, results, function(result){
        // alldone, clientnumber in result
     })
})


function doclient(clientnumber, done, todo, results, callback)
{
    if(done >= todo)
    {
        return callback(clientnumber);
    }
    else
    {
        var client = results[done];
        if(client){
            clientnumber++;
            var city = client.city;
            shops.find({"_id":city},function(err,resCursor){
                resCursor.toArray(function(err,bson){
                    //does stuff using the city, client number variables and data from "shop"
                    //including another find and each operation

                    // call next client
                    setImmediate(doclient, clientnumber, ++done, todo, results, callback);
                });
            });
        }
        else
        {
            // call next client
            setImmediate(doclient, clientnumber, ++done, todo, results, callback);
        }
    }
}