我为什么不在async函数中使用try...catch?

总之一句话:在async函数中使用try...catch会导致调试难道增加。且任何使用使用try...catch的场景,都会增加调试难度,比如react的报错信息,有的时候,你怎么都找不到问题代码具体在哪个位置。

当一个Error产生的时候,Error会用stack字段记录该Error产生的具体位置。只有,我们得到原始的Error,才能获得原始的stack信息,但是通过try...catch语法,往往会屏蔽原始的Error,导致我们追逐不到错误的原始位置。比如:

<script>
  'use strict'

  async function calc() {
    try {
      const x = await a + await b
      const y = x + await z
      return y
    }
    catch (e) {
      alert('计算错误')
    }
  }

  calc()
</script>

我们用alert来替代我们经常使用的toast, popup等方法。一旦我们通过交互形式接住错误时,我们就直接放弃了获得错误原始信息的权利。

async函数本质上是创建一个异步函数,而非创建一个封闭式的闭包。没错,如果你在async函数中使用try...catch跟使用闭包没有什么区别。异步函数的目标,是完成异步操作,但其中重要的一点是,它的错误是可以被捕获的。为了实现这种捕获,有些开发者会在 catch 中再次把错误抛出来,比如 catch (e) { throw e }。但是这样做,会导致程序在这里又结束了。所以,这种做法又不符合在async函数中使用try...catch的目的。

对于我个人而言,我从来不直接在async函数中使用try...catch,定义async函数是一个纯粹的async...await结构,在使用该函数时,使用.then().catch().finally()接住函数执行过程中的结果逻辑。

已有2条评论
  1. rxxy 2021-01-14 17:28

    要正确使用

  2. rxliuli 2021-01-13 12:07

    有点误人子弟了。。。async 函数中的 try/catch 和 then/catch 没什么区别吧?