【问题标题】:Can I use multiple 'await' in an async function's try/catch block?我可以在异步函数的 try/catch 块中使用多个“等待”吗?
【发布时间】:2018-05-27 22:58:33
【问题描述】:

async asyncfunction(){
  try{
    await method1();
    await method2();
  }
  catch(error){
    console.log(error);
  }
}

给定 method1() 和 method2() 是异步函数。每个 await 方法是否应该有一个 try/catch 块?有没有更干净的方法来写这个?我试图避免 '.then' 和 '.catch' 链接。

【问题讨论】:

标签: javascript asynchronous


【解决方案1】:

使用一个包含多个await 操作的try/catch 块很好。

await 运算符存储其父 async 函数的执行上下文并返回到事件循环。当await 运算符以其操作数的稳定状态和值被回调时,它将继续执行。

在恢复时,await 恢复之前保存的执行上下文,并返回操作数承诺的履行值作为await 表达式的结果,或者抛出被拒绝操作数的拒绝原因。

try/catch 块调用是保存和恢复之前和之后执行上下文的一部分。因此,多个await 操作不会干扰它们共享的外部try 块的行为。 catch 块将被调用,并带有在被拒绝的 try 块中等待的任何承诺的拒绝原因。

【讨论】:

    【解决方案2】:

    虽然@traktor answer 是正确的,但我想补充一个非常重要的警告。

    下面的代码sn-p是不安全的:

    async function foo() {
      try {
        const p1 = method1();
        const p2 = method2();
    
        await p1;
        await p2;
      } catch (e) {
        console.log(e);
      }
    }
    

    如果两个 Promise 都被拒绝,代码将在 NodeJS 中生成 UnhandledPromiseRejectionWarning,如果选项 --unhandled-rejections 设置为 throw(这将成为 Node 15 的默认行为),则可能会终止进程。

    为什么会这样?

    在问题的原始代码中,异步方法是按顺序调用的;即,如果第一个方法失败(承诺被拒绝),则永远不会调用第二个方法。

    但是,此答案开头的代码并行调用了两个异步方法;即,无论第一种方法是否成功,都会调用第二种方法。

    在这种情况下,只有第二种方法的promise上的await以第一种方法的成功为条件。意思是,如果第一个方法失败,则永远不会等待第二个方法(已经开始)的承诺,所以如果它也失败了,它将导致处理的承诺拒绝。

    如何克服这种行为?

    假设我们希望以相同的方式处理这两个拒绝,我们可以使用Promise.all

    try {
      const p1 = method1();
      const p2 = method2();
      
      await Promise.all([p1, p2]);
    } catch (e) {
      console.log(e);
    }
    

    只有第一个被拒绝的 Promise 会“触发”catch 子句,而第二个 Promise 会被静默忽略而不会导致进程崩溃。

    【讨论】:

      【解决方案3】:

      使用 Async.js 库 让我们谈谈使用 async.js 库以避免回调地狱。

      根据 async.js 的官方网站:Async 是一个实用模块,它为处理异步 JavaScript 提供了直接、强大的功能。

      Async.js 总共提供了近 70 个函数。现在,我们将只讨论其中的两个,即 async.waterfall() 和 async.series()。

      async.waterfall() 当您想要一个接一个地运行一些任务然后将上一个任务的结果传递给下一个任务时,此方法很有用。它需要一个函数数组“tasks”和一个最终的“callback”函数,该函数在“tasks”数组中的所有函数完成或使用错误对象调用“callback”之后调用。

      async.js library

      【讨论】:

        猜你喜欢
        • 2021-11-27
        • 1970-01-01
        • 2019-02-11
        • 2017-02-06
        • 2018-12-28
        • 1970-01-01
        • 2017-05-11
        • 2018-03-21
        • 2020-11-13
        相关资源
        最近更新 更多