手写一个实现 ES8 async/await 的转换器

阅读时长 8 分钟读完

在前端开发中,我们经常需要用到异步编程,以确保我们的程序可以正确地运行。异步编程的方式有很多种,其中一种比较常用的方式是使用 Promise。然而,在某些情况下,使用 Promise 会显得比较繁琐。ES8 引入了 async/await 语法来简化异步编程,使得我们可以像写同步代码一样写异步代码。

但是,并不是所有的浏览器都支持 ES8 的 async/await 语法。为了确保我们的代码可以在所有的浏览器上正常运行,我们可以使用一个转换器来将 async/await 语法转换成可以在所有浏览器上运行的代码。

在本文中,我们将手写一个实现 ES8 async/await 的转换器,并详细解释每个步骤的实现方法。

实现步骤

  1. 开始时,我们需要将 async/await 语法转换成生成器函数,并将其中的 await 表达式转换成 yield 表达式。

示例代码:

转换成:

  1. 接下来,我们需要实现 run 函数,它的作用是执行生成器函数。我们需要创建一个迭代器对象,并使用 next 方法执行生成器的第一个 yield 表达式,然后根据表达式返回的值继续执行后面的代码。

示例代码:

-- -------------------- ---- -------
-------- ------------ -
  ----- ------ - ----------
  -------- --------- -
    ----- --------- - -----------------
    -- ----------------- -
      ---------------------------
    -
  -
  -------
-
  1. 实现 step 函数,它的作用是根据返回值来决定向下执行还是等待。如果返回值是一个 Promise 对象,我们需要等待这个对象返回结果后再继续执行。如果返回值不是 Promise 对象,我们直接继续执行。

示例代码:

-- -------------------- ---- -------
-------- --------- -
  ----- --------- - -----------------
  -- ----------------- -
    -- ---------------- ---------- -------- -
      ---------------------------
    - ---- -
      ----------------------
    -
  -
-
  1. 实现 async/await 的转换器。我们遍历代码中的所有函数,并将其中的 async 关键字去掉,将 await 关键字转换成普通的函数调用。然后将其包装成一个立即执行的函数,并将其中所有用到的变量都传递进去。

示例代码:

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

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

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

示例代码

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

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

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

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

总结

本文手写了一个实现 ES8 async/await 的转换器,并详细解释了每个步骤的实现方法。虽然我们可以使用现有的工具来完成这个任务,但是手写一遍可以让我们更深入地理解异步编程和生成器函数的相关概念。同时,这个转换器对于我们在不支持 async/await 的浏览器上运行代码非常有用。

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

纠错
反馈