Promise.all如何捕获错误与Promise.allSettled

885 阅读2分钟

Promise.allSettledPromise.all的最大不同:Promise.allSettled永远不会被reject

1、Promise.all

  • 这种方法通常用于多个相关异步任务且其工作相互依赖的情况
const promises = [
  Promise.resolve('Kylin'),
  Promise.resolve('Arms')
];

Promise.all(promises).then((res) => console.log(res));

// 最终输出: [ 'Kylin', 'Arms' ]

image.png

  • 尽管能用catch捕获其中的异常,但其他执行成功的Promise的消息都丢失了,无法获取到
const promises = [
  Promise.resolve('Kylin'),
  Promise.resolve('Arms'),
  Promise.reject('Navy')
];

Promise.all(promises)
  .then((res) => console.log(res))
  .catch((err) => console.log(err));

// 最终输出: Navy

image.png

2、Promise.allSettled

  • 使用 Promise.allSettled([])Promise.all([]) 类似,但不同之处在于它会等待所有输入的 promises 完成或被拒绝,并返回描述每个 promise 结果的对象数组。
  • 场景:通常用于处理不互相依赖的异步操作
  • Promise.allSettled需要处理每一个返回的错误
  • 所有Promise的数据都被包含在then语句中,且每个Promise的返回值多了一个status字段,表示当前Promise的状态,可以根据此状态进行对错误的处理
const testPromise = Promise.reject('错误!');

Promise.allSettled([
  getWeaknessRuleCascader(),
  getTerminalList(),
  testPromise
]).then((res) => {
  console.log(res, 'allSettled');
});
  • 结果对象有 3 个属性:
    • status"fulfilled"要么"rejected",表示 Promise 的最终状态。
    • value :仅在 status === 'fulfilled'时出现。Promise 兑现的值。
    • reason:仅在 status === 'rejected' 时出现。Promsie 拒绝的原因。

3、Promise.all([])的捕获错误方式

  • 使用以下函数包裹Promise.all要执行的并发请求,会遍历每一个请求,不管是resolve还是reject的结果都将返回
let transferPromise = (reqList) => {
  return reqList.map((item) => {
    return item.then((res) => res).catch((rej) => rej);
  });
};
  • 以下代码中transferPromise函数包裹的每个函数是具体项目中向后端请求的方法
Promise.all(
      transferPromise([
        getWeaknessRuleCascader(),
        getRiskRuleEnum(),
        getDataLabelsCascader(),
        getApiStateOptions(),
        getNetworkSegmentCascade(),
        getNewFeatureLabels(),
        getTerminalList(),
        getCustomFields(),
        getDataLabelList()
      ])
    )
      .then(
        ([
          weaknessRes,
          ruleRes,
          labelCascaderRes,
          stateRes,
          networkRes,
          featureRes,
          terminalRes,
          customFieldRes,
          labelRes
        ]) => {
          ...// 具体的业务逻辑
        }
      )
      .catch((err) => {
        console.error(err);
      });
  • 在使用transferPromise这个函数包裹Promise.all中的数组时,在then中使用数组解构得到的数据就是每个请求得到的结果,如果哪个请求报错也是在这个结果中,如下图所示: