记一篇让我搞不懂的eventloop

67 阅读2分钟

我总是很迷惑,是宏任务先执行呢?还是微任务先执行呢?来一段代码看看吧

console.log(1)


setTimeout(()=>{console.log(2)},1000)


Promise.resolve().then(()=>{console.log(3)})


Promise.resolve().then(()=>{setTimeout(()=>{console.log(4)},1000)})


Promise.resolve().then(()=>{console.log(5)})


setTimeout(()=>{console.log(6)},1000)


console.log(7)

结果输出竟然是 1 7 3 5 2 6 4

那么哪些是宏任务呢?setTimeout

哪些是微任务呢?Promise

是不是很清晰了呢?代码是先执行的微任务,再执行的宏任务

你是否也会奇怪?4 为什么是最后输出的呢?

我们看看具体到底是怎么执行的?

1. js代码是从上到下逐行的执行,同步的代码,执行后便会立即输出

2. 当遇到微任务,它会将这段代码加入到微任务队列中

3. 当遇到宏任务的时候,它也会将这段代码加入到宏任务队列中

4. 接下来就要执行微任务队列中的代码了,当微任务队列中的代码执行完毕,微任务队列也会被清空

5.微任务队列清空,接下来就要执行宏任务队列中的代码了,同样,当宏任务队列中的代码执行完毕,宏任务队列也会被清空

Promise.resolve().then(()=>{setTimeout(()=>{console.log(4)},1000)}) 可以看到,当这个微任务执行的时候,宏任务队列中已经加入了两个宏任务了,只能再在后面追加这里面的宏任务了,所以最后输出的是4咯

让我们再来看一段代码

Promise.resolve().then(()=>{
    console.log('p1')
    setTimeout(()=>{
        console.log('s2')
    },1000)
})

setTimeout(()=>{
    console.log('s1')
    Promise.resolve().then(()=>{
        console.log('p2')
    })
},1000)

结果输出竟然是 p1 s1 p2 s2

这段代码也蛮有意思的,真正的体现了事件循环这个机制。其实就是微任务队列执行->宏任务队列执行->微任务队列执行->宏任务队列执行...循环执行直到代码执行完毕

1. 代码执行,第一轮,微任务队列中有 p1 啦,宏任务队列中有 s1 啦,至于里面的代码需要等到微/宏任务队列执行的时候才能看到咯

2. 第二轮,微任务队列中有 p2 啦,宏任务队列中有 s2 啦

3. 秉着微任务先执行,宏任务后执行的原则,输出是不是就是 p1 s1 p2 s2 啦,其实关键在于遇到微/宏任务它是先加入到任务队列中,然后执行微任务队列,再执行宏任务队列。

是不是清晰啦!

这种东西总是会忘,所以想记录一下,总结的可能不太好,欢迎大家指点哈~