-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ES6 系列之 Babel 将 Async 编译成了什么样子 #103
Comments
async function foo() {
console.log(1)
await console.log(2)
console.log(4)
}
foo()
console.log(3) @mqyqingfeng 大佬你好,请问能从源码的角度帮忙分析下,为什么3比4先输出吗? |
我好像理解了,希望大佬指点下 function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
}
if (info.done) {
resolve(value);
} else {
Promise.resolve(value).then(_next, _throw);
}
} 每执行完一次 next,如下: var info = gen[key](arg); 如果 info.done 不为 true,就使用 Promise 等待当前 value 值,如果是个普通值,就进入到 then,继续执行 _next 方法。这样就形成了一个 Promise 的嵌套。
如果将 async 函数转换成 promise 的写法,可能是这样的: const fetchValue = async function () {
var value1 = await fetchData(1);
var value2 = await fetchData(value1);
var value3 = await fetchData(value2);
return value3;
};
function fetchValue() {
return new Promise((resolve) => {
Promise.resolve(fetchData(1)).then((value1) => {
Promise.resolve(fetchData(value1)).then((value2) => {
Promise.resolve(fetchData(value2)).then((value3) => {
resolve(value3);
});
});
});
});
} 这样将 async 方法换成 promise 的写法,上面3为比4先输出的问题,就很好理解了 |
async function foo() {
console.log(1)
await console.log(2)
console.log(4)
}
foo()
console.log(3) 实际上等价于 async function foo() {
console.log(1)
await Promise.resolve(console.log(2))
console.log(4)
}
foo()
console.log(3) 这样写的话看起来就好理解了,先输出1,再输出2,然后有个异步的过程,这样3就会被输出,最终输出4 |
我认为理解generator和async await从协程和事件循环的角度理解会更好 |
console.log(4) 在await 下一行执行,可以算是在微任务(promise.then中),所以执行完123,在打印4 |
前言
本文就是简单介绍下 Async 语法编译后的代码。
Async
Babel
我们直接在 Babel 官网的 Try it out 粘贴上述代码,然后查看代码编译成什么样子:
_asyncToGenerator
regeneratorRuntime 相关的代码我们在 《ES6 系列之 Babel 将 Generator 编译成了什么样子》 中已经介绍过了,这次我们重点来看看 _asyncToGenerator 函数:
以上这段代码主要是用来实现 generator 的自动执行以及返回 Promise。
当我们执行
fetchValue()
的时候,执行的其实就是_asyncToGenerator
返回的这个匿名函数,在匿名函数中,我们执行了这一步就相当于执行 Generator 函数,举个例子:
var gen = fn.apply(this, arguments)
就相当于var hw = helloWorldGenerator();
,返回的 gen 是一个具有 next()、throw()、return() 方法的对象。然后我们返回了一个 Promise 对象,在 Promise 中,我们执行了 step("next"),step 函数中会执行:
step("next") 就相当于
var info = gen.next()
,返回的 info 对象是一个具有 value 和 done 属性的对象:接下来又会执行:
value 此时是一个 Promise,Promise.resolve(value) 依然会返回这个 Promise,我们给这个 Promise 添加了一个 then 函数,用于在 Promise 有结果时执行,有结果时又会执行
step("next", value)
,从而使得 Generator 继续执行,直到info.done
为 true,才会resolve(value)
。不完整但可用的代码
请原谅我水了一篇文章……
ES6 系列
ES6 系列目录地址:https://github.com/mqyqingfeng/Blog
ES6 系列预计写二十篇左右,旨在加深 ES6 部分知识点的理解,重点讲解块级作用域、标签模板、箭头函数、Symbol、Set、Map 以及 Promise 的模拟实现、模块加载方案、异步处理等内容。
如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎 star,对作者也是一种鼓励。
The text was updated successfully, but these errors were encountered: