Event Loop 事件循环题解法

145 阅读3分钟

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。

前言

大家好,我是cv竹叶, 前端打印输出题,是面试笔试上必不可少的一到题,今天来学学吧!

答案在页尾部哈!

首先,要先弄明白js代码执行机制,分别有同步异步异步事件队列暂存,事件队列的执行还会分出宏任务微任务

他们之间的执行顺序为:

  1. 同步代码,按顺序先执行。
  2. 异步代码先放一边。
  3. 同步代码执行完成之后,再执行事件队列中的任务,先执行微任务,再执行宏任务

所以按照上面的执行方式,我们只要知道一些函数方法是同步还是异步,宏任务,还是微任务,解题就很容易了!

同步:

console.log(1);//同步

new Promise((resolve,reject) => {
    console.log(2) // 同步 resolve() 
}).then(() => {})

输出:1 2

异步:

setTimeout(() => {
    // 异步:宏任务1 setTimeout
    console.log(1)
}, 0)
//先按顺序执行完微任务,再按顺序执行宏任务
new Promise((resolve,reject) => {
    resolve() 
}).then(() => { 
    // 异步:微任务1
    console.log(2)
    setTimeout(() => { 
        console.log(3) // 异步:宏任务2 setTimeout
    })
}).then(()=>{
    //异步:微任务2
    console.log(4)
    setTimeout(() => { 
        console.log(5) // 异步:宏任务3 setTimeout
    })
})
先找出执行异步微任务:2 4
再找出执行异步宏任务:1 3 5
输出:2 4 1 3 5

含有return的异步

new Promise((resolve, reject) => {
    console.log(1) //同步
    resolve() 
}).then(() => {
    // 多了个return
    return new Promise((resolve, reject) => {
        console.log(2) //微任务中的同步
        resolve()
    }).then(() => { 
        console.log(3) //微任务中的异步微任务
    }).then(() => { 
        // 相当于return了这个then的执行返回Promise
        console.log(4) //微任务中的异步微任务
    }) 
}).then(() => {
    console.log(5)//微任务
})

含有return的异步,就当是接到当前的then之前执行微异步,上面想当于:
new Promise((resolve, reject) => {
    console.log(1)//同步
    resolve() 
}).then(() => {
    console.log(2) // 多了个return
    new Promise((resolve, reject) => {
        console.log(3) //微任务中的异步微任务
        resolve()
    }).then(() => { 
        console.log(4) //微任务中的异步微任务
    }).then(() => { 
        console.log(5)//微任务中的异步微任务
    }).then(() => {
        console.log(6)//微任务中的异步微任务
    }) 
})
输出:1 2 3 4 5 6

含有async和await的异步:

async function async1() {
    console.log(1);//同步
    await async2();
    console.log(2);//异步微任务
}
async function async2() {
    console.log(3);//同步
}
console.log(4);//同步
setTimeout(function () {
    console.log(5);//异步宏任务
});
async1()
new Promise(function (resolve, reject) {
    console.log(6);//同步
    resolve();
}).then(function () {
    console.log(7);//微任务
});
console.log(8);//同步

找到async里是同步:4 1 3
Promise里也是同步:6 8
await下面是异步微任务:2
then是异步微任务:7
setTimeout是异步宏任务:5
最终输出:4 1 3 6 8 2 7 5

练习题目

题1、同步,异步宏任务

setTimeout(function () {
    console.log(1)
}, 0)

new Promise(function (resolve) {
    console.log(2)
    for (var i = 0; i < 10; i++) {
        i == 9 && resolve()
    }
    console.log(3)
}).then(function () {
    console.log(4)
})
console.log(5)

题2、同步,多个异步宏任务

console.log(1)
setTimeout(() => {
    console.log(2)
}, 0)
console.log(3)
Promise.resolve().then(() => {
    console.log(4)
}).then(() => {
    console.log(5)
})
console.log(6)

题3、同步、多个异步微任务、多个异步宏任务

new Promise((resolve, reject) => {
    console.log(1)
    resolve()
}).then(() => {
    console.log(2)
    setTimeout(() => {
        console.log(3)
    }, 0);
}).then(() => {
    console.log(4)
    setTimeout(() => {
        console.log(5)
    }, 0);
})

题4、含有return的

new Promise((resolve, reject) => {
    console.log(1)
    resolve() 
}).then(() => {
    return new Promise((resolve, reject) => {
        console.log(2)
        resolve()
    }).then(() => { 
        console.log(3)
    }).then(() => { 
        console.log(4) 
    }) 
}).then(() => {
    console.log(5)
})

题5、含有async和await的

async function async1() {
    console.log(1);
    await async2();
    console.log(2);
}
async function async2() {
    console.log(3);
}
console.log(4);
setTimeout(function () {
    console.log(5);
});
async1()
new Promise(function (resolve, reject) {
    console.log(6);
    resolve();
}).then(function () {
    console.log(7);
});
console.log(8);

题6、原地毕业题

async function async1() {
    console.log(1);
    await async2();
    console.log(2);
}
async function async2() {
    console.log(3);
    setTimeout(function () {
        console.log(4);
    });
}
console.log(5);
setTimeout(function () {
    console.log(6);
});
async1()
new Promise(function (resolve, reject) {
    console.log(7);
    setTimeout(function () {
        console.log(8);
    });
    resolve();
}).then(function () {
    console.log(13);
    return new Promise(function (resolve, reject) {
        console.log(9);
        setTimeout(function () {
            console.log(10);
        })
        resolve()
    }).then(() => {
        console.log(11);
        setTimeout(function () {
            console.log(12);
        })
    });
});
console.log(14);

答案

题1输出:2 3 5 4 1
题2输出:1 3 6 4 5 2
题3输出:1 2 4 3 5
题4输出:1 2 3 4 5
题5输出:4 1 3 6 8 2 7 5
题6输出:5 1 3 7 16 2 9 10 12 14 6 4 8 11 13 15

题6解法:
先找出,同步:5 1 3 7 16
再找出异步微任务:2 9 10 12 14 
最后找出异步宏任务:6 4 8 11 13 15

解题口诀:先同步,再异步微任务,最后异步宏任务

结言

最终护士小姐姐还是放弃学前端了T.T点个赞安慰一下我吧

1635230269(1).png