Promise.allSettled()

Promise.allSettled() 方法返回一个 Promise,在所有给定的 promise 都已经 fulfilled 或 rejected 之后才会 resolve,并带有一个对象数组,每个对象表示对应的 promise 结果。

1. 何时使用

当你有多个彼此不依赖的异步任务,或者总想知道每个 promise 的结果时,通常使用它。

相比之下,Promise.all() 更适合彼此相互依赖,或者其中任何一个 reject 时立即结束的场景。

2. 示例

const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
const promises = [promise1, promise2];

Promise.allSettled(promises)
  .then((results) => results.forEach((result) => console.log(result.status)));

// expected output:
// "fulfilled"
// "rejected"

3. 与 Promise.all 的核心区别

特性Promise.allPromise.allSettled
任何一个 reject立即 reject不中断,等所有都 settle
返回值成功结果数组每项含 status、value/reason 的对象数组
适用相互依赖、任一失败即放弃多个独立任务、希望全部跑完
// allSettled 的结果格式
[
  { status: 'fulfilled', value: 3 },
  { status: 'rejected', reason: 'foo' }
]

4. 简单实现

function allSettled(promises) {
  return new Promise((resolve) => {
    if (promises.length === 0) {
      resolve([]);
      return;
    }

    const results = new Array(promises.length);
    let count = 0;

    for (let index = 0; index < promises.length; index++) {
      Promise.resolve(promises[index]).then(
        (value) => addResult(index, { status: 'fulfilled', value }),
        (reason) => addResult(index, { status: 'rejected', reason })
      );
    }

    function addResult(i, res) {
      results[i] = res;
      count++;
      if (count === promises.length) {
        resolve(results);
      }
    }
  });
}

关键点:把 settle 计数与结果写入分开处理,每次完成都判断是否所有 promise 都已 settle;位置用 results[i] 而非 push,确保即便后完成的 promise 也能写到正确的下标。

来源整理自:vue3js.cn 面试官系列