我最近开始使用promises,所以我可以等到我在执行下一个函数之前用x个记录更新数据库。我发现自己计算循环迭代,以便在正确的时间解决承诺。例如:
var updateAccounts = function(accounts) {
var promise = new Promise(function(resolve, reject) {
var counter = 0;
accounts.forEach(function(account) {
db.collection('accounts').update({
name: account.name
}, {
$set: {
balance: account.balance
}
});
counter++
if (counter == accounts.length) {
resolve('accounts updated');
}
});
}
});
return promise;
}
有没有办法等到循环完成而不计算迭代次数?它只是感觉有点hacky,但我不确定它是否真的是一个问题。
答案 0 :(得分:4)
根据MDN:
Promise对象表示异步操作的最终完成(或失败)及其结果值。
基本上这意味着Promise
应该跟踪单个异步操作的结果。
但是,在您的示例中,您已在一个db.collection('accounts').update(...)
内执行了多个异步操作(即Promise
)。你不得不诉诸于互动计数来追踪完整性,而不是依赖于这样做的承诺。
要解决此问题(双关语:D),您的每个异步请求都应该有自己的Promise
。
由于您有多个更新,因此有多个承诺,因此您可以使用Promise.all
来捕获所有承诺成功完成的时间。
这里是您的代码示例的快速改编:
var updateAccounts = function(accounts) {
var promises = [];
accounts.forEach(function(account) {
var promise = new Promise(function(resolve, reject) {
db.collection('accounts').update({
name: account.name
}, {
$set: {
balance: account.balance
}
});
});
promises.push(promise);
});
Promise.all(promises).then(function(arrPromises) {
console.log("All promises resolved.");
}).catch(function(failedPromise) {
console.log("Something failed.");
});
}
我的示例中唯一缺少的是resolve
成功执行后调用db.collection('accounts').update(...)
。更新成功完成后,您必须调用resolve
,或者如果更新失败,则必须调用reject
。这就是它已经完成的承诺。
我的代码示例在没有它的情况下无法工作,但是从原始代码示例中不清楚哪个应该指定db.collection('accounts').update(...)
的回调 - 所以我省略了它
答案 1 :(得分:0)
你可以尝试一下foreach吗?
var updateAccounts = function(accounts) {
var promise = new Promise(function(resolve, reject) {
...
accounts.forEach(function(account) {
...
});
<---Here<--
}
});
return promise;
}
&#13;