前言:本来一直觉得自己对事件循环的理解还是可以的,但是当问了我一道很绕的题之后,我有点蒙圈了,所以还是需要加强巩固一下
废话不多说,直接上题
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
setTimeout() => {
console.log('time1');
}, 0)
}
async function async2() {
console.log('async2 start');
setTimeout(() => {
console.log('time2');
}, 0)
new Promise((resolve) => {
resolve();
console.log('promise start');
}).then(() => {
console.log('promise then');
});
}
async1();
Promise.resolve().then(() => {
console.log('promise resolve then');
})
setTimeout(() => {
console.log('time3');
}, 0)
console.log('start')
我们先说下await后面的代码会相当于在Promise.resolve().then里面进行执行
例如
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
setTimeout() => {
console.log('time1');
}, 0)
}
相当于
function async1() {
console.log('async1 start');
async2();
Promise.resolve().then(() => {
console.log('async1 end');
setTimeout() => {
console.log('time1');
}, 0)
})}
分析如下:
- 整体 script 作为第一个宏任务进入主线程,先执行async1方法,遇到同步任务console.log('async1 start')执行,输出
async1 start
- 继续往下执行,遇到async2方法,进入到async2方法中,遇到同步任务console.log('async2 start'),输出
async2 start
- 继续往下执行,遇到setTimeout(() => {console.log('time2');}, 0),标记为宏任务1,将其放到宏任务队列中
- 执行到promise中,遇到console.log('promise start')同步任务,输出
promise start
- 遇到then函数() => {console.log('promise then'),我暂时标记为then1,分到的微任务队列中
- async1函数继续执行,遇到console.log('async1 end'),标记为then1,放到微任务队列中
- 在then1里面遇到setTimeout,将()=> {console.log('time1')},标记为宏任务2,放到宏任务队列中
- 然后再继续往下找同步任务,到Promise.resolve().then(() => {console.log('promise resolve then');}),将其标记为then1,把其放到微任务队列里
- 继续往下,遇到setTimeout宏任务,把()=> {console.log('time3')},标记为宏任务1,将其推到宏任务列表中
- 继续往下执行,发现console.log('start')同步任务,输出
start
,同步任务执行完毕 - 第一个宏任务执行完毕,开始执行微任务,先进先出,找到then1,依次输出promise then,async1 end,promise resolve then
- 微任务执行完毕,继续寻找宏任务,开始执行宏任务,先进先出,找到宏任务1,依次输出time2,time3
- 最后找到宏任务2,输出time1
最后得出答案
async1 start
async2 start
promise start
start
promise then
async1 end
promise resolve then
time2
time3
time1
仅仅是自己的理解,如果有不对的地方,欢迎指出,非常感谢