Promise.all 异常处理

让 Promise.all 在某个请求失败后继续返回其他成功的结果

问题

使用 Promise.all() 处理多个并发请求时,只要有一个 Promise 被拒绝,整个 Promise.all 就会立即进入 reject 状态,导致其他正常返回的数据也无法使用。如何让 Promise.all 在某个请求失败后依然能获取其他成功的结果?

解答

方案一:捕获单个 Promise 的错误

Promise.all 中使用 map 为每个 Promise 添加 .catch() 处理,将错误转换为正常的返回值,确保所有 Promise 都能正常 resolve。

const p1 = new Promise((resolve, reject) => {
  resolve('p1');
});

const p2 = new Promise((resolve, reject) => {
  resolve('p2');
});

const p3 = new Promise((resolve, reject) => {
  reject('p3 error');
});

Promise.all([p1, p2, p3].map(p => p.catch(e => ({ error: e }))))
  .then(values => {
    console.log(values);
    // ['p1', 'p2', { error: 'p3 error' }]
  })
  .catch(err => {
    console.log(err);
  });

方案二:使用 Promise.allSettled

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

const p1 = new Promise((resolve, reject) => {
  resolve('p1');
});

const p2 = new Promise((resolve, reject) => {
  resolve('p2');
});

const p3 = new Promise((resolve, reject) => {
  reject('p3 error');
});

Promise.allSettled([p1, p2, p3])
  .then(results => {
    console.log(results);
    // [
    //   { status: 'fulfilled', value: 'p1' },
    //   { status: 'fulfilled', value: 'p2' },
    //   { status: 'rejected', reason: 'p3 error' }
    // ]
  });

关键点

  • Promise.all 遇到第一个 reject 就会立即失败,丢弃所有结果
  • 方案一通过 .catch() 将错误转为正常值,适合需要自定义错误处理的场景
  • 方案二使用 Promise.allSettled 更语义化,返回统一的结果格式
  • Promise.allSettled 返回的每个对象包含 statusvalue/reason 字段
  • 根据业务需求选择方案:需要区分成功失败用方案二,需要自定义错误值用方案一