ES9 中的 async/await 实现原理及其错误处理方法

阅读时长 7 分钟读完

在 JavaScript 的发展历程中,回调地狱和异步编程一直是个让前端开发者头疼的问题。随着 ES7 中的 async/await 异步函数的普及,前端开发变得更加容易。在 ES9 中,async/await 获得了更进一步的升级。本文将为大家讲解 ES9 中的 async/await 实现原理及其错误处理方法。

async/await 简介

async/await 是 ES7 引入的 JavaScript 异步编程解决方案,能够显式地将异步操作转换成同步代码的形式。async/await 基于 Promise 机制,简化了 Promise 的写法,并且可以在不阻塞程序的情况下等待 Promise 返回。它允许程序员通过暂停和恢复异步函数执行的方式编写直观的代码,以及通过非常简单的同步编程模型来解决常见的异步问题。

async/await 基础语法

async/await 的语法极其简单。在函数声明前面加上 async 关键字,表示该函数内部会有异步操作,函数内部使用 await 操作符等待异步操作的结果。

下面是一个返回 Promise 的异步函数,以及使用 async/await 语法写的示例代码:

-- -------------------- ---- -------
-------- ----------- -
  ------ --- --------------- -- -
    ------------- -- -
      --------------- ---------
    -- ------
  ---
-

----- -------- ------ -
  ----- ---- - ----- ------------
  ------------------ -- --------- ------
-

-------

main 函数内使用了 async/await 语法,以同步的方式使用 fetchData 函数。首先在 fetchData 中使用 setTimeout 模拟异步操作,等待 1 秒后返回 Promise。在 main 函数中,使用 await 操作符等待 fetchData 函数的返回结果,并将结果赋值给 data 变量。之后输出结果。

async/await 错误处理

由于 async/await 基于 Promise,因此我们可以使用 Promise 的错误处理方式处理异步中的错误。可以使用 trycatch 语句块来捕获 Promise 异常。示例代码如下:

-- -------------------- ---- -------
-------- ----------- -
  ------ --- ----------------- ------- -- -
    ------------- -- -
      ---------- ------------- -- ----- --------
    -- ------
  ---
-

----- -------- ------ -
  --- -
    ----- ---- - ----- ------------
  - ----- ------- -
    ------------------- -- --- ------ ------ -- ----- ----
  -
-

-------

fetchData 函数返回的 Promise 在 1 秒后将会被拒绝(reject)。在 main 函数中使用 try...catch 语句来捕获异常。当 fetchData 函数抛出错误时,错误将被捕获并在控制台中打印。

实现原理

了解了 async/await 的语法和错误处理方法之后,我们来看看它是如何实现的。

其实,async/await 仍然建立在 Promise 基础之上,只是使用了 Generator 函数。Generator 函数提供了一种返回值之间交替执行顺序的方法。而 await 操作符就是在 Generator 函数的基础上打了一个包装。 async function 创建一个异步的函数,返回值是一个 Promise 对象。当此函数执行时,返回的结果是一个 Promise 对象,可以使用 then 或者 catch 方法获取返回值。

下面是一个使用 Generator 函数模拟实现 await 的代码:

-- -------------------- ---- -------
-------- ------------------------------- -
  ------ ---------- -
    ----- --------- - ------------------------- -----------

    ------ --- ----------------- ------- -- -
      -------- --------- ---- -
        --- --------------- - -----
        --- -
          -- -- --------- --
          --------------- - --------------------
        - ----- ----- -
          ------------
        -
        ----- - ------ ---- - - ----------------

        -- ------ -
          ---------------
        - ---- -
          -- -- -------
          ------ ----------------------------
            --------------- -
              ------------ -------
            --
            --------------- -
              ------------- -------
            -
          --
        -
      -

      -------------
    ---
  --
-

-------- ----------- -
  ------ --- ----------------- -- -
    ------------- -- -
      --------------- ---------
    -- ------
  ---
-

----- --------- - -------------------------- ------ -
  ----- ---- - ----- ------------

  ------------------ -- --------- ------

  ----- ------ - ----- ---------------------

  -------------------- -- ------
---

------------

在上述代码中,我们获得了一个传入 Generator 函数 generatorFunc 的参数,并将其作为 this 上下文调用。我们创建了一个 step 方法,其中接收一个参数 key 和另一个 arg 参数。通过 generator[key](arg) 调用 Generator 函数并执行,如果产生异常则通过 reject 函数被捕获。

如果没有异常,我们解析生成器结果,并从 value 继续执行或执行 catch函数。如果 done 尚未采用,我们将通过执行return Promise.resolve(value).then(...)返回一个已解决(resloved)的 Promise, 然后回到 step('next', reslovedValue) 并开始执行yield下一个返回值。

结论

本文介绍了 ES9 中的 async/await 实现原理及其错误处理方法。我们了解了 async/await 的基础语法,并使用示例代码演示了错误处理方法。最后,我们通过代码实现了一个简单的 async/await 模拟版本。希望本文能够帮助你更好地理解异步编程和 ES9 中的 async/await 的实现原理。

参考资料

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/670e297c5f551281025fdebb

纠错
反馈