标签: await

  • 记一个 `try…catch` 异步函数的坑

    记一个 `try…catch` 异步函数的坑

    前几天遇到一个问题:想捕获异步函数的错误,但是捕获不到。我的代码大概是这样:

    try {
      (async () => {
        // 一大堆异步函数
      })();
    } catch (e) {
      if (e.message.startsWith('my error:') {
        // 我的错误,提示一下即可
      } else {
        // 某种不知名错误,继续抛出
        throw new Error(e.message);
      }
    }

    不知道读者是否发现问题,我当时是左看右看没看出来。后来只好写最小用例缩小问题范围,终于找到问题所在:异步函数前面缺少 await。于是想通了,上面的代码其实被引擎解释成:

    1. try 一个函数
    2. 这个函数的返回值是一个 Promise
    3. Promise 是正常对象,所以 try 成功
    4. 至于 Promise 里的函数是否失败,不关 try 的事,所以自然捕获不到

    所以正确的写法是:

    // 外面先套一层,不然不能用 await
    (async () => {
      try {
        // 再加上 `await`
        await (async () => {
          // 异步函数体
        })();
      } catch (e) {
        // ....
      }
    })();

    这个 await 至关重要。这是异步函数的一大特性,即 try...catch 可以捕获整个异步操作前后所有栈的异常,而不仅仅是当前函数的异常。同时我们也要注意,异步函数的调用可能并不在当前栈,也无法被 try...catch 在当前栈捕获到错误。

  • JavaScript 异步开发全攻略

    JavaScript 异步开发全攻略

    之前在 GitChat 做过一次分享:《JavaScript 异步开发全攻略》。在我看来,原始内容可能不够完美,但通过后来的维护,可以把它打磨得越来越好。昨天在 SF 上回答了一个 Vuex 的 action 里使用 Promise 的问题,然后就想去补充一下这方面的内容。结果发现 GitChat 竟然不支持编辑文章,只能把内容发给运营人工修改。

    索性把内容放到 Gitbook 上好了,反正 GitChat SEO 也不做,文章也自然移动到第二页了。试了试,没有被墙,很好。于是简单整理了一下,上传。

    欢迎阅读,欢迎分享,因为我会不时更新新内容,请关注 star:

    JavaScript 异步开发全攻略