构建协调并行的 Promise.allSettled
2023-12-08 14:28:07
了解 Promise.all 和 Promise.allSettled:异步 JavaScript 的利器
在现代 JavaScript 开发中,Promise
已成为处理异步代码的基石。Promise
使我们能够以更简洁、更可读的方式编写代码,而不必使用繁琐的回调函数。
Promise.all
是一个强大的工具,它允许我们等待一组 Promise
都完成。这对于并行执行多个异步任务非常有用。但是,Promise.all
有一个缺点:它不会告诉我们哪个 Promise
被拒绝了。
ES2020 引入了 Promise.allSettled
方法来解决这个问题。Promise.allSettled
返回一个包含所有传入 Promise
结果的数组,无论它们是成功完成还是被拒绝。这使得我们可以轻松地处理并行任务,并获取每个任务的状态和结果。
Promise.all
Promise.all
接收一个由 Promise
组成的数组,并返回一个 Promise
。这个 Promise
在所有传入的 Promise
都完成或有一个 Promise
被拒绝时才完成。
如果所有传入的 Promise
都成功完成,那么 Promise.all
返回的 Promise
将被解析,其值为一个包含所有传入 Promise
结果的数组。如果至少有一个传入的 Promise
被拒绝,那么 Promise.all
返回的 Promise
将被拒绝,其值为第一个被拒绝的 Promise
的拒绝原因。
代码示例:
const promises = [
fetch('https://example.com/api/users'),
fetch('https://example.com/api/posts'),
fetch('https://example.com/api/comments')
];
Promise.all(promises)
.then(responses => {
// 所有请求都完成
})
.catch(error => {
// 至少有一个请求被拒绝
});
Promise.allSettled
Promise.allSettled
的用法与 Promise.all
类似,但是它返回一个包含所有传入 Promise
结果的数组,无论这些 Promise
是成功完成还是被拒绝。
Promise.allSettled
返回的数组中的每个元素都是一个对象,这个对象包含两个属性:status
和 value
。status
属性的值为 "fulfilled"
或 "rejected",表示该
Promise 是成功完成还是被拒绝。
value属性的值为该
Promise` 的结果或拒绝原因。
代码示例:
const promises = [
fetch('https://example.com/api/users'),
fetch('https://example.com/api/posts'),
fetch('https://example.com/api/comments')
];
Promise.allSettled(promises)
.then(results => {
for (const result of results) {
if (result.status === "fulfilled") {
// 该 Promise 成功完成
console.log(result.value);
} else {
// 该 Promise 被拒绝
console.error(result.reason);
}
}
});
何时使用 Promise.all 和 Promise.allSettled
Promise.all
最适合于需要等待所有传入的 Promise
都完成的情况。例如,你可能有一个程序,它需要在继续执行后续操作之前从多个 API 中获取数据。
Promise.allSettled
最适合于需要处理并行任务并获取每个任务的状态和结果的情况。例如,你可能有一个程序,它需要处理多个文件,但你并不关心它们处理的顺序。
常见问题解答
1. Promise.all
和 Promise.allSettled
有什么区别?
Promise.all
等待所有传入的 Promise
都完成,而 Promise.allSettled
无论 Promise
的状态如何都返回一个包含所有结果的数组。
2. 我应该总是使用 Promise.allSettled
吗?
不,只有在你需要处理并行任务并获取每个任务的状态和结果时才使用 Promise.allSettled
。在其他情况下,Promise.all
更适合。
3. 我可以同时使用 Promise.all
和 Promise.allSettled
吗?
是的,你可以根据需要在你的代码中结合使用 Promise.all
和 Promise.allSettled
。
4. Promise.all
和 Promise.allSettled
支持哪些浏览器?
Promise.all
和 Promise.allSettled
都在现代浏览器中得到广泛支持。对于旧的浏览器,可以使用 bluebird
或 es6-promise
等库。
5. 如何在 Node.js 中使用 Promise.all
和 Promise.allSettled
?
Node.js 本身支持 Promise
。你可以使用 Promise.all
和 Promise.allSettled
,就像在浏览器中一样。