async function async1() {
console.log("a");
const res = await async2();
console.log("b");
}
async function async2() {
console.log("c");
return 2;
}
console.log("d");
setTimeout(() => {
console.log("e");
}, 0);
async1().then(res => {
console.log("f")
})
new Promise((resolve) => {
console.log("g");
resolve();
}).then(() => {
console.log("h");
});
console.log("i");
/**
* 输出结果:d a c g i b h f e
*/
解释:1.执行console.log(“d”)
2.setTimeout的回调放入宏任务执行console.log(“e”)
3.然后开始执行async1中的console.log(“a”)。
4.接下来就是await关键字语句。Await后面调用的是async2函数,因此我们将其放入调用栈。
5.然后开始执行async2中的console.log(“c”),并return一个值。执行完成后,async2就被移出调用栈。
6.这时候,await会阻塞async2的返回值,先跳出async1进行往下执行。需要注意的是,现在async1中的res变量,还是undefined,没有赋值。
7.紧接着是执行new Promise。执行console.log(“g”)
8.执行console.log(“i”)
9.async1外面的同步任务都执行完成了,因此就重新回到前面阻塞的位置,进行往下执行。
10.这时res成功赋值了async2的结果值,然后往下执行console.log(“b”)。
11.这时候async1才算是执行结束,紧接着再将其调用的then()函数放入微任务队列中。console.log(“b”)
12.这时script宏任务已经全部执行完了,开始准备清空微任务队列了。第一个被执行的微任务队列是promise then,也就是将执行其中的console.log(“h”)语句。
13.执行完Promise then微任务后,紧接着开始执行async1的promise then微任务。
14.这时候微任务队列已经清空了,即开始执行下一个宏任务。