我找不到让我的查找功能起作用的方法。 我想从账单集合中找到所有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查询数据库。对此有任何帮助表示赞赏。
如果您需要任何澄清,请告诉我。
提前致谢!
答案 0 :(得分:0)
如果Transactions.find
函数是异步的,那么它的回调会在for ... in
周期结束很久之后的某个时间点运行。那时,billId
具有在for ... in
周期的最后一次运行时分配的值。因此,回调的所有运行都会打印出该值。
如果您想保留该值,则必须在某处创建closure,如下所示:
(function (id) {
Transactions.find(..., function (...) {
// ... use `id` here
});
})(billId);
如果bills
是Array
,或者您使用的是Lo-Dash等实用程序库,则可以使用Array.prototype.map
或{{1}等迭代函数使用闭包,这样你就不必单独创建一个闭包。
答案 1 :(得分:0)
循环内闭包函数的经典错误。
您的变量值会更改每个循环步骤。另一方面,当变量已多次更改时,您的函数将在稍后(一段时间后)执行。
查看链接以获得澄清:
Creating closures in loops: A common mistake
答案 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);
});