Promise.allSettled()的用法
Promise.allSettled()是一个JavaScript方法,它返回一个promise,在所有给定的promise都完成(成功或失败)后完成。与Promise.all()方法不同,Promise.allSettled()方法不会因为某个promise失败而导致整个操作失败,它会等待所有的promise都完成,然后返回一个包含所有promise状态的数组。
示例代码
const promise1 = Promise.resolve("foo");
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("bar");
}, 100);
});
Promise.allSettled([promise1, promise2, promise3]).then(results => {
results.forEach(result => {
if (result.status === "fulfilled") {
console.log(`promise fulfilled with value: ${result.value}`);
} else if (result.status === "rejected") {
console.log(`promise rejected with reason: ${result.reason}`);
}
});
});
// expected output:
// "promise fulfilled with value: foo"
// "promise fulfilled with value: 42"
// "promise rejected with reason: bar"
在上面的示例中,我们使用Promise.allSettled()方法等待三个promise完成。其中两个promise(promise1和promise2)都成功完成,第三个promise(promise3)失败了。然后我们循环遍历结果数组,并在控制台中打印每个promise的状态和值。
总之,Promise.allSettled()方法可以让你等待所有给定的promise都完成,然后返回一个包含它们所有状态的数组。这对于需要处理多个并行操作的情况非常有用。
取水果和蔬菜
在深入研究 Promise.allSettle() 之前,我们先定义两个简单的 helper 函数。
首先,resolveTimeout(value, delay)返回一个 promise ,该 promise 在经过 delay 时间后用 value 来实现
function resolveTimeout(value, delay) {
return new Promise(
resolve => setTimeout(() => resolve(value), delay)
);
}第二,rejectTimeout(reason, delay) - 返回一个 promise,在经过 delay 时间后拒绝reason。
最后,我们使用这些辅助函数来试验 promise.allsettle()。
1.All promises fulfilled
我们同时访问当地杂货店的蔬菜和水果。访问每个列表是一个异步操作:
const statusesPromise = Promise.allSettled([
resolveTimeout(['potatoes', 'tomatoes'], 1000),
resolveTimeout(['oranges', 'apples'], 1000)
]);
// wait...
const statuses = await statusesPromise;
// after 1 second
console.log(statuses);
// [
// { status: 'fulfilled', value: ['potatoes', 'tomatoes'] },
// { status: 'fulfilled', value: ['oranges', 'apples'] }
// ]Promise.allSettled([...])返回一个 promise statusesPromise,该 promise 在1秒内解决,就在蔬菜和水果被解决之后,并行地解决。
statusesPromise 解析为一个包含状态的数组。
- 数组的第一项包含有蔬菜的已完成状态:status: 'fulfilled', value: ['potatoes', 'tomatoes'] }
- 同样的方式,第二项是水果的完成状态: { status: 'fulfilled', value: ['oranges', 'apples'] }
2.一个 promise 被拒绝
想象一下,在杂货店里已经没有水果了。在这种情况下,我们拒绝水果的 promise。
promise.allsettle() 在这种情况下如何工作?
const statusesPromise = Promise.allSettled([
resolveTimeout(['potatoes', 'tomatoes'], 1000),
rejectTimeout(new Error('Out of fruits!'), 1000)
]);
// wait...
const statuses = await statusesPromise;
// after 1 second
console.log(statuses);
// [
// { status: 'fulfilled', value: ['potatoes', 'tomatoes'] },
// { status: 'rejected', reason: Error('Out of fruits!') }
// ]Promise.allSettled([...]) 返回的 promise 在 1 秒后解析为一个状态数组:
- 数组的第一项,蔬菜 promise 成功解析:{ status: 'fulfilled', value: ['potatoes', 'tomatoes'] }
- 第二项,因为水果 promise 被拒绝,所以是一个拒绝状态: { status: 'rejected', reason: Error('Out of fruits') }
即使输入数组中的第二个 promise 被拒绝,statusesPromise仍然会成功解析一个状态数组。
3.所有的 promises 都被 rejected
如果杂货店里的蔬菜和水果都卖光了怎么办?在这种情况下,两个 promise 都会被拒绝。
const statusesPromise = Promise.allSettled([
rejectTimeout(new Error('Out of vegetables!'), 1000),
rejectTimeout(new Error('Out of fruits!'), 1000)
]);
// wait...
const statuses = await statusesPromise;
// after 1 second
console.log(statuses);
// [
// { status: 'rejected', reason: Error('Out of vegetables!') },
// { status: 'rejected', reason: Error('Out of fruits!') }
// ]在这种情况下,statusesPromise仍然成功地解析为一个状态数组。然而,该数组包含被拒绝的promise 的状态。
总结
Promise.allSettled(promises)可以并行地运行 promise,并将状态(fulfilled 或reject)收集到一个聚合数组中。Promise.allSettled(...)在你需要执行平行和独立的异步操作并收集所有结果时非常有效,即使某些异步操作可能失败。
本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!