我最近开始使用 Promise,这样我就可以等到我用 x 条记录更新数据库后再执行下一个函数。我发现自己正在计算循环迭代,以便在正确的时间解决 promise 。例如:
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;
}
有没有办法等到循环完成而不计算迭代次数?感觉有点老套,但我不确定这是否真的是一个问题。
最佳答案
根据MDN :
The Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value.
基本上这意味着 Promise
应跟踪单个异步操作的结果。
但是,在您的示例中,您在一个 db.collection('accounts').update(...)
内执行了多个异步操作(即 Promise
) 。您必须依靠交互计数来跟踪完整性,而不是依赖 promise 来做到这一点。
要解决此问题(双关语:D),每个异步请求都应该有自己的 Promise
。
由于您有多个更新,因此有多个 promise ,因此您可以使用 Promise.all
捕获所有 promise 何时成功完成。
以下是对您的代码示例的快速修改:
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
。这就是它已经完成的 promise 。
如果没有这个,我的代码示例将无法工作,但从原始代码示例中不清楚应该在哪里指定 db.collection('accounts').update(...)
的回调。 ——所以我省略了它。
关于javascript - 如何避免在 JavaScript Promises 中计算循环迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44599083/