期望Promise.all全成败后触发方法,为何finally()不生效?
搞定啦!用
Promise.allSettled()替代Promise.all()就行 哈哈,我懂你的困惑!你本来以为Promise.all().finally()会等所有Promise不管成功失败都跑完再触发,结果发现只要有一个Promise reject,finally就立刻执行了——这其实是Promise.all()的特性在搞鬼!
Promise.all()是个急性子,只要其中一个Promise被reject,它会立刻终止并抛出reject,根本不会等剩下的Promise执行完,所以它的.finally()自然就提前触发了。
而你真正需要的,是一个能耐心等所有Promise都「尘埃落定」(不管是成功resolve还是失败reject)的方法,这时候Promise.allSettled()就派上用场了!它会老老实实等所有Promise都执行完毕,才会进入后续的.then()或.finally()。
给你改好的示例代码:
var p3 = new Promise((resolve, reject) => { setTimeout(() => { console.log('three fails'); reject({ data: 'three' }); }, 2000); }); var p4 = new Promise((resolve, reject) => { setTimeout(() => { console.log('four succeeds'); resolve({ data: 'four' }); }, 3000); }); // 把Promise.all换成Promise.allSettled就行! Promise.allSettled([p3, p4]).finally(() => { console.log('所有Promise都跑完啦!不管成功失败,我现在才触发~'); });
执行起来的顺序是这样的:
- 第2秒:
p3失败,打印three fails - 第3秒:
p4成功,打印four succeeds - 紧接着,
finally触发,打印那句收尾的话
要是你还想看看每个Promise的具体结果,还能加个.then()处理:
Promise.allSettled([p3, p4]) .then(results => { results.forEach((result, index) => { if (result.status === 'fulfilled') { console.log(`Promise ${index+1} 成功:`, result.value); } else { console.log(`Promise ${index+1} 失败:`, result.reason); } }); }) .finally(() => { console.log('所有Promise都处理完毕,该干活啦!'); });
这样就完全符合你的需求啦!
内容的提问来源于stack exchange,提问作者PrimeLens
相关产品推荐
相关产品推荐

