Mongoose find() 回调问题

Mongoose find() issues with callbacks

我找不到让查找功能正常工作的方法。 我想从账单集合中找到所有 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,但是当我尝试获取它们在第二个 Find (Transactions.find()) 中,它们重复最后一个 id。 因此,在当前状态下,我无法为每个 ID 查询数据库。对此的任何帮助表示赞赏。

如果您需要任何说明,请告诉我。

提前致谢!

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

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

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

如果 bills 是一个 Array 或者如果您正在使用像 Lo-Dash 这样的实用程序库,您可以使用像 Array.prototype.map 或 [=18= 这样的迭代函数] 使用闭包,因此您不必单独创建闭包。

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

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

查看链接以进行说明:

在循环中创建闭包:常见错误

JavaScript 循环内闭包——简单实用的例子

Javascript infamous Loop issue?

完美!

感谢大家的提示。我使用 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);  
});