防止Promise.all在出现第一个错误时被拒绝的规范方法是什么?

时间:2019-05-16 19:30:32

标签: javascript promise es6-promise

我有以下代码

await doAllCats();
await doAllDogs();
console.log("Finished processing Cats and Dogs ")

function doAllCats() {
  let promiseArray = [];
  for(let cat of cats) {
    promiseArray.push(doOneCat(cat));
  }
  return Promise.all(promiseArray);
}
function doOneCat(cat) {
  let promise = doSomeAsyncStuffWithACat(cat);
  promise.catch((err)=> {
    console.error("there was a problem with "+cat+" but processing should continue as normal for the other cats and dogs");
  })
  return promise; 
}

当所有“猫狗”都成功时,它工作正常。但是,有时一只猫会失败,而发生这种情况时,我会在最高级别遇到一个例外。处理猫失败的代码位于doOneCat内部,并且运行正常。但是,失败的承诺仍在promiseArray中,因此我过早地“完成了”。

防止Promise.all拒绝第一个例外的最简单/规范的方法是什么?

2 个答案:

答案 0 :(得分:1)

只需返回捕获的Promise,这样拒绝就不会冒到Promise.all为止(然后它不会退出):

 return promise.catch((err) => {
   console.error("there was a problem with "+cat+" but processing should continue as normal for the other cats and dogs");
    return /*some flag that indicates that this one did throw */;
 });

将来,Promise.allSettled将解决确切的情况。

答案 1 :(得分:0)

我相信这些是可用的选项:-

  1. 乔纳斯的回答。我试图实现这一点,但没有成功。这可能是我的错误实现,因为我的doOneCat()是几层嵌套的方法和一个嵌套的Promise。

  2. 使用由Randy链接的https://github.com/tc39/proposal-promise-allSettled中的库。

  3. 重构,以完全避免https://blog.logrocket.com/elegant-error-handling-with-the-javascript-either-monad-76c7ae4924a1和其他建议中的拒绝/捕获。

我最终选择了选项3。我重构了低级代码以使用包含成功/失败标志的响应对象进行解析,而我的高级代码则对该标志进行测试以执行适当的成功/失败处理。这样,我的Promise.all只会看到成功解决的Promises。恕我直言,这种重构产生的代码比我以前拥有的rej / catch代码更具可读性。