Mongoose find()回调问题

时间:2015-01-03 12:08:42

标签: javascript node.js callback mongoose

我找不到让我的查找功能起作用的方法。 我想从账单集合中找到所有billId,然后检查交易数据库中的每个billId。

问题是,由于aSynch - 我估计,id在我的循环上没有更新。 这是代码:

Bills.find({type: bill_type, endDate: {"$gte" : new Date(year + "-" + month + "-1")}}).find(function(err, bills){
        if(err)
            res.send(err);

        details.bills = bills;

        for(key in bills){
            var billId = bills[key]._id;
            console.log("BillId: " + billId); // Here the ids are unique (which is what I want)

             Transactions.find({billId : billId}, function(err, transactions){
                if (err) {
                    console.log('error: '+ err)
                } else {
                    console.log("Transaction BillId: " + billId); // Here I get always the same ID - which is not quiet what I need.
                }
            });


            //console.log(transactions);
        }

       res.send(details);  
    });

控制台的结果是:

BillId: 549bf0597886c3763e000001
BillId: 54a014bfac01ca3526000001
BillId: 54a015753547a6c026000001

^好结果 - 来自for()中的第一个console.log。

然后:

Transaction BillId: 54a015753547a6c026000001
Transaction BillId: 54a015753547a6c026000001
Transaction BillId: 54a015753547a6c026000001

^结果不好 - 它重复了for()的最后一个结果,我需要所有结果。

在第一个console.log()中,当我从第一个find()(Bills.find())得到结果时,我可以看到日志中的所有id但是当我尝试将它们放入第二个时查找(Transactions.find()),他们重复上一个ID。 所以在这个当前状态下,我无法为每个id查询数据库。对此有任何帮助表示赞赏。

如果您需要任何澄清,请告诉我。

提前致谢!

3 个答案:

答案 0 :(得分:0)

如果Transactions.find函数是异步的,那么它的回调会在for ... in周期结束很久之后的某个时间点运行。那时,billId具有在for ... in周期的最后一次运行时分配的值。因此,回调的所有运行都会打印出该值。

如果您想保留该值,则必须在某处创建closure,如下所示:

(function (id) {
    Transactions.find(..., function (...) {
        // ... use `id` here
    });
})(billId);

如果billsArray,或者您使用的是Lo-Dash等实用程序库,则可以使用Array.prototype.map或{{1}等迭代函数使用闭包,这样你就不必单独创建一个闭包。

答案 1 :(得分:0)

循环内闭包函数的经典错误。

您的变量值会更改每个循环步骤。另一方面,当变量已多次更改时,您的函数将在稍后(一段时间后)执行。

查看链接以获得澄清:

Creating closures in loops: A common mistake

JavaScript closure inside loops – simple practical example

Javascript infamous Loop issue?

答案 2 :(得分:0)

完美!

感谢提示家伙。我使用Underscore each function解决了这个问题。

以下是: 我没有使用for进行循环,而是简单地将for替换为_.each,如下例所示:

Bills.find({type: bill_type, endDate: {"$gte" : new Date(year + "-" + month + "-1")}}).find(function(err, bills){
    if(err)
        res.send(err);

    details.bills = bills;

    _.each(bills, function(item){        
        var billId = item._id; 
        console.log("BillId: " + billId); 

         Transactions.find({billId : billId}, function(err, transactions){
            if (err) {
                console.log('error: '+ err)
            } else {
                console.log("Transaction BillId: " + billId);
            }
        });


        //console.log(transactions);
    });

   res.send(details);  
});