Promise.all 和 Promise.allSettled 的区别

理解两种并行处理 Promise 方法的不同行为和使用场景

问题

Promise.allPromise.allSettled 有什么区别?什么时候该用哪个?

解答

核心区别

Promise.allSettled 永远不会被 reject,而 Promise.all 会在任何一个 Promise 失败时立即 reject。

Promise.all 的行为

当所有 Promise 都成功时,Promise.all 工作得很好:

const delay = n => new Promise(resolve => setTimeout(resolve, n));

const promises = [
  delay(100).then(() => 1),
  delay(200).then(() => 2),
];

Promise.all(promises).then(values => console.log(values));
// 输出: [1, 2]

但一旦有一个 Promise 失败,其他成功的结果都会丢失:

const promises = [
  delay(100).then(() => 1),
  delay(200).then(() => 2),
  Promise.reject(3)
];

Promise.all(promises)
  .then(values => console.log(values))
  .catch(err => console.log(err));
// 输出: 3
// 前两个成功的结果丢失了

这是 Promise.all 的”要么全部成功,要么全部重来”的逻辑。

Promise.allSettled 的行为

Promise.allSettled 会等待所有 Promise 完成(无论成功或失败),并返回每个 Promise 的状态和结果:

const promises = [
  delay(100).then(() => 1),
  delay(200).then(() => 2),
  Promise.reject(3)
];

Promise.allSettled(promises).then(values => console.log(values));
// 输出:
// [
//   {status: "fulfilled", value: 1},
//   {status: "fulfilled", value: 2},
//   {status: "rejected", reason: 3}
// ]

所有 Promise 的信息都被保留,可以根据 status 字段判断每个 Promise 的执行结果。

关键点

  • Promise.all 在任何一个 Promise 失败时立即 reject,成功的结果会丢失
  • Promise.allSettled 等待所有 Promise 完成,返回每个 Promise 的状态和结果
  • Promise.all 适合”全部成功才有意义”的场景
  • Promise.allSettled 适合需要知道每个 Promise 执行情况的场景
  • Promise.allSettled 的结果包含 status 字段(“fulfilled” 或 “rejected”)和对应的 valuereason