返回

构建协调并行的 Promise.allSettled

前端

了解 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 返回的数组中的每个元素都是一个对象,这个对象包含两个属性:statusvaluestatus 属性的值为 "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.allPromise.allSettled 有什么区别?

Promise.all 等待所有传入的 Promise 都完成,而 Promise.allSettled 无论 Promise 的状态如何都返回一个包含所有结果的数组。

2. 我应该总是使用 Promise.allSettled 吗?

不,只有在你需要处理并行任务并获取每个任务的状态和结果时才使用 Promise.allSettled。在其他情况下,Promise.all 更适合。

3. 我可以同时使用 Promise.allPromise.allSettled 吗?

是的,你可以根据需要在你的代码中结合使用 Promise.allPromise.allSettled

4. Promise.allPromise.allSettled 支持哪些浏览器?

Promise.allPromise.allSettled 都在现代浏览器中得到广泛支持。对于旧的浏览器,可以使用 bluebirdes6-promise 等库。

5. 如何在 Node.js 中使用 Promise.allPromise.allSettled

Node.js 本身支持 Promise。你可以使用 Promise.allPromise.allSettled,就像在浏览器中一样。