深入解析:为什么async/await被称为Generator函数的语法糖
作者:闭包旅人时间:2026-10-23 09:35:02浏览:193
本文深入解析JavaScript中async/await与Generator函数的关系,论证前者是后者的语法糖。通过对比使用async/await实现sleep功能与将其转换为Generator配合Promise自执行器的代码,揭示其底层执行原理及Babel转译的大致逻辑。
async/await与Generator的关系概述
在阮一峰的ES6入门教程中,关于async函数的介绍指出:
async函数本质上就是Generator函数的语法糖。
那么,为何会有这样的说法呢?
首先,假设存在一个异步操作,我们可以利用async/await语法以同步代码的形式来模拟异步执行过程。
代码实现与原理转换
下面演示如何使用async/await来实现一个sleep(睡眠)功能。
function sleep(time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1);
}, time);
});
}
async function test () {
for(let i = 0; i < 10; i++) {
let result = await sleep(1000);
console.log(result);
}
}
接下来,我们将上述async/await代码转换为使用Generator函数和Promise来实现的方式。
let test = function () {
// ret 为一个Promise对象,因为ES6语法规定 async 函数的返回值必须是一个 promise 对象
let ret = _asyncToGenerator(function* () {
for (let i = 0; i < 10; i++) {
let result = yield sleep(1000);
console.log(result);
}
});
return ret;
}();
// generator 自执行器
function _asyncToGenerator(genFn) {
return new Promise((resolve, reject) => {
let gen = genFn();
function step(key, arg) {
let info = {};
try {
info = gen[key](arg);
} catch (error) {
reject(error);
return;
}
if (info.done) {
resolve(info.value);
} else {
return Promise.resolve(info.value).then((v) => {
return step('next', v);
}, (error) => {
return step('throw', error);
});
}
}
step('next');
});
}
观察以上代码,逻辑是否变得清晰可见?将async/await改写为Generator的关键,在于利用Promise实现一个Generator的自执行器。Babel编译器的内部原理与此大致相同。
总结
以上就是本文的全部内容,希望这些内容对大家的JavaScript学习或工作有所参考,感谢支持。
作者最新文章
什么时候该用JS构造器:与工厂模式、字面量的选择对比
2026-11-05 16:18:22
推荐几款轻量级JS照片墙开源库及对比
2026-11-05 15:56:19
JavaScript递归写法有哪些常见陷阱及避免方法
2026-11-05 14:53:38
JS数组浅拷贝与深拷贝怎么选?场景与方法总结
2026-11-05 14:41:02
p5.js 中 setup() 和 draw() 函数的执行机制详解
2026-11-05 12:32:38
