什么是 async/await
在 ES6 中,我们通过 Promise 处理异步操作。但是 Promise then 函数内的代码还是需要过多的 callback 嵌套,难以维护这就是 async/await 方法被提出的原因。async/await 让 JavaScript 代码看起来更像是同步代码,而不是异步。
async 定义函数为异步函数,await 等待 Promise 对象完成。await 关键字只能在异步函数中使用,它暂停异步函数的执行,并等待 Promise 对象返回结果。等到 Promise 对象返回结果,再继续执行 async 函数。
-- -------------------- ---- ------- -------- ----------- -- - ------ --- --------------- -- - ------------- -- - --------- - --- -- ------ --- - ----- -------- --------------- - ------------------ -------- ---------- ----- ------ - ----- ----------- --- ------------------ -------- --------- -------- - ---------------- ------------------- -----------
上面代码中,我们通过 await 等待 multiply 函数返回 Promise 对象。
运行结果:
Async function started Script finished Async function result: 6
async/await 的好处
- 更加清晰,代码风格优雅;
- 可以轻松地处理 Promise 中的错误;
- 捕获的异常可以直接是具体的代码位置。
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。
import "core-js/stable"; import "regenerator-runtime/runtime";
这里引入了 core-js 和 regenerator-runtime,这是两个对于不兼容 Promise、Generator 的浏览器所必需的打补丁。
按需加载模块 (Browser):
import "core-js/stable"; import "regenerator-runtime/runtime"; import 'core-js/es7/array'; // 标准方法 import 'core-js/es/object'; // 标准方法
按需加载模块 (Node):
require("core-js/stable"); require("regenerator-runtime/runtime"); require('core-js/es7/array'); // 标准方法 require('core-js/es/object'); // 标准方法
需要为 Babel 添加 transform-runtime 插件来使用 above polyfill:
-- -------------------- ---- ------- - ---------- - - ---------------------------------- - --------- ---- --------------- ---- - - - -
示例代码
-- -------------------- ---- ------- -- ------- ------ ----------------- ------ ------------------------------ ------ ------- - ----- ------ ----- --------- - ----- ---- - ----- ---------- -------------------- ------ -- --
-- -------------------- ---- ------- -- --------------- -------------- - - -------- - ------------------------------- -- -------- - - ---------------------------------- - ------- -- -- -- -- --
结论
在使用 async/await 时,如果需要兼容较旧的浏览器/运行环境,在使用 Babel 进行相关转换时,需要加入 require("babel-polyfill") 。但是要注意,该方法在引入之后,可能会增加一些兼容性问题。因此,正确使用针对特定运行环境的 polyfill 是更好的选择。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/66f002c56fbf96019731a46e