async await的执行流程
一直没有关注await这个关键字,只知道await如何使用、await是类似于resolve成功回调的作用,以前的实现中通过 new Promise(resolve => resolve()),但是在优化以后变为了Promise.resolve()。在面试时做到有关于事件循环的问题。 下面的问题不涉及到 async和Promise的优先级判断,只是普通的同步异步判断,用来重新认识Generator+Promise == async 与 await 的过程
setTimeout(() => {console.log(0)}, 0)
{ //Node 不允许直接写自执行匿名函数,应该放在大括号内
(async function(){
console.log(1)
await Promise.resolve()
console.log(2)
})()
}
console.log(3)
new Promise(reslve => {
console.log(4)
}).then(res => {
console.log(5)
}).catch(err => {
console.log(6)
})
const p = new Promise((resolve, reject) => {
console.log(7)
resolve(8)
})
p.then(res => {
console.log(res)
}).then(res => {
console.log(9)
})
p.then(res => {
console.log(10)
})
{
(async () => {
console.log(11)
await Promise.resolve(333)
console.log(12)
})()
}
解析
注意:async修饰的函数是一个同步执行的函数,但是当遇到了await,await后的所有代码块变为了微任务,如果再遇到了await,此时是上一个await的then中的任务,也就是微任务,此时能够从生成器和Promise结合中进行解释。
复习生成器
使用
function*定义,特殊的在类中的另外一种语法*[Symbol.iterator](){} || *iterator(){}也是可以的。通过关键字yield分割代码块,通过关键字yield分割的代码块类似一个一个的函数。
- 生成器是特殊的迭代器
- 通过yield控制代码运行,yield类似函数,能够接收和返回。
const msg = yield 'Hello JS'function request(msg) { return new Promise((resolve, reject) => { resolve(msg) }) } function* getBanners() { // 每一次的yield都代表着then链式的代码块 let msg = yield "Hello JS"; msg = yield request(msg + "aaa"); msg = yield request(msg + "bbb"); msg = yield request(msg + "ccc"); console.log(msg); } // 手动实现,将每一个步骤都和Promise联系起来 const generator = getBanners("Hello JS"); Promise.resolve(generator.next().value).then((res) => { generator.next(res).value.then((res) => { generator.next(res).value.then((res) => { generator.next(res).value.then((res) => { generator.next(res); // 最后可以进行调用 }); }); }); }); // 自动实现(递归方式有多少次yield,就进行计算) let val = generator.next().value /* 初始next */ function co(generator) { if (val === undefined) { /* base case */ return ; } if (val instanceof Promise) { val.then(res => { val = generator.next(res).value co(generator) }) return ; } val = generator.next(val).value co(generator) } co(generator)
- 经过解析这一阶段,基本上也就是实现了async和await的功能,简单来说yield就是await的功能,同时也能够从实现中发现,await就是类似resolve的语法糖,如果是普通的值那么包裹一层
Promise.resolve即可完成Promise对象的转化。 - 总结:async 与 await == Promise + Generator await后面的代码都会变成微任务的形式。
答案
最主要的还是async和await的同步的异步(微任务,比Promise优先级更高)。
1
3
4
7
11
2
8
10
12
9 注意:这里是因为箭头函数返回最后一行,有返回值,即使没有显式的resolve
0