ES7 async/await 使用 Babel 转换时要加入 require("babel-polyfill") 吗

阅读时长 5 分钟读完

什么是 async/await

在 ES6 中,我们通过 Promise 处理异步操作。但是 Promise then 函数内的代码还是需要过多的 callback 嵌套,难以维护这就是 async/await 方法被提出的原因。async/await 让 JavaScript 代码看起来更像是同步代码,而不是异步。

async 定义函数为异步函数,await 等待 Promise 对象完成。await 关键字只能在异步函数中使用,它暂停异步函数的执行,并等待 Promise 对象返回结果。等到 Promise 对象返回结果,再继续执行 async 函数。

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

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

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

上面代码中,我们通过 await 等待 multiply 函数返回 Promise 对象。

运行结果:

async/await 的好处

  1. 更加清晰,代码风格优雅;
  2. 可以轻松地处理 Promise 中的错误;
  3. 捕获的异常可以直接是具体的代码位置。

Babel 是什么

Babel 是一个 JavaScript 编译器,可以将 ES6/ES7 代码转换成 ES5 标准的 JavaScript 代码。Babel 对一些最新标准的支持转换是逐步更新的。因此,某些最新特性的语法糖(如 async/await 等)是需要使用 Babel 来进行转换的。

require("babel-polyfill") 是什么

需要了解的是,async/await 是在 ES7 中加入的,而 ES7 尚未被所有的浏览器/运行环境广泛地支持,比如 IE 或者 node.js 的旧版本,那么为了兼容更多运行环境,我们使用 Babel 转换时,需要考虑 ES7 语法的兼容性。

Babel 转换 async/await 时需要带上 require("babel-polyfill") 。因为在使用 await 的时候需要先进入等待,也就是执行异步函数(Promise),所以必须先申明它是异步的,然后再转换成 ES5 标准的 JavaScript 代码。因此需要使用追加额外运行时依赖的形式。

babel-polyfill 会在宿主环境中注入一个完整的 ES6+ 环境,同时还会添加内置的 regenerator-runtime,并扩展全局对象。需要注意的是,这个 reinject 的过程依赖于对象,此时该对象未定义则会抛出异常。

require("babel-polyfill") 的兼容性问题

由于是追加额外运行时依赖,所以容易造成一些兼容性问题,因此需要我们对运行环境进行判断,不需要全部引用,而只是使用那些不兼容的 polyfill 在已知环境中使用。

我们可以根据目录结构来判断,是否需要使用 polyfill。

这里引入了 core-js 和 regenerator-runtime,这是两个对于不兼容 Promise、Generator 的浏览器所必需的打补丁。

按需加载模块 (Browser):

按需加载模块 (Node):

需要为 Babel 添加 transform-runtime 插件来使用 above polyfill:

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

示例代码

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

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

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

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

结论

在使用 async/await 时,如果需要兼容较旧的浏览器/运行环境,在使用 Babel 进行相关转换时,需要加入 require("babel-polyfill") 。但是要注意,该方法在引入之后,可能会增加一些兼容性问题。因此,正确使用针对特定运行环境的 polyfill 是更好的选择。

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

纠错
反馈