事件循环之实战题目

63 阅读2分钟

前言:本来一直觉得自己对事件循环的理解还是可以的,但是当问了我一道很绕的题之后,我有点蒙圈了,所以还是需要加强巩固一下

废话不多说,直接上题

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

仅仅是自己的理解,如果有不对的地方,欢迎指出,非常感谢