在JavaScript中的异步函数中捕获所有承诺拒绝

时间:2017-10-12 14:47:10

标签: javascript error-handling async-await es6-promise

在异步函数(javaScript-node v8.4.0)中等待多个promises抛出拒绝错误后,我遇到了捕获所有错误的问题。

参考以下javaScript:

作为参考,函数timeoutOne()和timeoutTwo()只返回一个原生的promise,它分别在1秒和2秒的超时后解析一个值,如果我设置" deviousState"则拒绝并返回错误。为真。

let deviousState = true;

async function asyncParallel() {
  try {
    let res1 = timeoutOne();
    let res2 = timeoutTwo();
    console.log(`All done with ${await res1} ${await res2}`)
  }
  catch(err) {
    console.log(err)
  }
}
asyncParallel();

let pAll = Promise.all([timeoutOne(), timeoutTwo()]);
pAll.then((val) => {
  console.log(`All done with ${val[0]} ${val[1]}`)
}).catch(console.log);

在这两种情况下,只有返回的promise才会记录错误。我知道在一些promise库中有一种方法可以记录所有错误(例如"解决蓝鸟中的#34;方法),但是,我不确定这种方法是否有类似物本地承诺?

此外,如果两个promise都拒绝,则asyncParallel()会记录一个未被捕获的错误,其中包含拒绝最后的承诺。那是因为async函数的try / catch块没有内置机制来以这种方式捕获多次拒绝吗?

如果承诺解决,两个实例中的所有内容都相同。只是当两者都拒绝时,Promise.all处理错误,async函数版本声明其中一个未处理的promise错误将在未来版本的节点中崩溃该进程。

无论如何,try / catch是否正确处理此类错误?或者我是否仍然需要在异步函数中使用Promise.all以确保错误得到正确处理?

1 个答案:

答案 0 :(得分:8)

  

如果两个承诺都拒绝,那么asyncParallel()会记录一个未被捕获的错误,其中包含拒绝最后的承诺。

是 - 您创建了timeoutTwo()承诺,但从未处理过错误(例如在await中使用它)。由于await res2中的例外,await res1从未执行过。

(注意它不是" 拒绝最后的承诺",但总是等待第二个承诺。

  

这是因为async函数的try / catch块没有内置机制来以这种方式捕获多次拒绝吗?

在顺序代码中,不会有多个异常,因此提出额外的语法来处理它们会很困难。

  

我是否仍需要在异步函数中使用Promise.all以确保错误得到正确处理?

是的,正是如此。如果您想要并行等待多个承诺,则始终使用Promise.allawait关键字仅适用于以下.then()电话。

你应该写

async function asyncParallel() {
  try {
    let [val1, val2] = await Promise.all([timeoutOne(), timeoutTwo()]);
    console.log(`All done with ${val1} ${val2}`)
  } catch(err) {
    console.log(err)
  }
}
  

在这两种情况下,只有返回的promise才会记录错误。我知道在一些promise库中有一种方法可以记录所有错误(例如"解决蓝鸟中的#34;方法),但是,我不确定这种方法是否有类似物本地承诺?

不,没有。使用settle以及您想要的任何值来实现then的特征是微不足道的:

async function asyncParallel() {
  try {
    let [stat1, stat2] = await Promise.all([
        timeoutOne().then(() => "one fulfilled", () => "one rejected"), 
        timeoutTwo().then(() => "two fulfilled", () => "two rejected")
    ]);
    console.log(`All settled with ${stat1} ${stat2}`)
  } catch(err) {
    console.log(err)
  }
}