我需要使用一些值迭代javascript中的一个数组,这些值将用于调用一个返回promise的异步函数。在没有完成所有承诺的情况下,我无法继续下一个代码部分。
在下面的示例中,函数"processInvoices“必须解析一个promise,直到其中的所有promise都完成(假设"confirmInvoice”是一个具有不同响应时间的异步函数):
processInvoices(invoices)
{
return new promise((resolve,reject)=>
{
invoices.forEach(number=>
{
confirmInvoice(number)
.then(result=>{
if (!result)
{reject('Error confirming the invoice');}
});
});
resolve(true); // Resolving here doesn´t mean that all promises were completed!
});
}
init() // triggered at load..
{
let invoices = [2,4,8,16,31];
processInvoices(invoices)
.then(result=>
{
if (result) // It´s probable that the following message isn´t accurate:
console.log('All invoices were processed');
}).catch(reason=>{console.error(reason)});
}
使用上面的代码,我不能确定"console.log (或任何例程)“是否会在所有承诺完成后立即执行。
更新 Promise.all(iterable)解决了这个问题:
processInvoices(invoices)
{
return new promise((resolve,reject)=>
{
var promisesArray = []; // store all promises here
invoices.forEach(number=>
{
promisesArray.push(confirmInvoice(number));
});
Promise.all(promisesArray).then (results=>{
// validate all results and reject if necessary...
if (validateResults(results)) {
// if all ok
resolve('All invoices were processed successfully');
}
else {
reject('Error processing one or more invoices'); // just for demo purposes
}
});
});
}
init() // triggered at load..
{
let invoices = [2,4,8,16,31];
processInvoices(invoices)
.then(result=>
{
console.log(result);
}).catch(reason=>{console.error(reason)});
}
发布于 2018-10-03 06:43:20
forEach
同步运行。如果您希望在整个processInvoices
解析之前等待所有承诺的解析,则应该改用Promise.all
;将每个发票号map
到一个Promise
,并对生成的承诺数组调用Promise.all
。另外,您的
if (!result) {resolve(false);}
这听起来像是在尝试处理错误,以防没有结果-在这种情况下,您应该拒绝Promise
而不是调用resolve
。理想情况下,失败的confirmInvoice
调用将导致被拒绝的Promise
,但是如果这不是您可以修复的,那么如果result
是False值,那么就抛出一个错误,这样您就可以在init
的catch
中处理它。例如:
function processInvoices(invoices) {
return Promise.all(
invoices.map(number => (
confirmInvoice(number)
.then(result => {
// This will result in the `Promise.all` rejecting:
if (!result) throw new Error('Failed to confirm invoice ' + number);
})
))
);
}
function init() {
const invoices = [2, 4, 8, 16, 31];
processInvoices(invoices)
.then(result => {
console.log('All invoices were processed');
})
.catch((err) => {
console.log('err: ' + err);
});
}
https://stackoverflow.com/questions/52617354
复制相似问题