我总是很迷惑,是宏任务先执行呢?还是微任务先执行呢?来一段代码看看吧
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 啦,其实关键在于遇到微/宏任务它是先加入到任务队列中,然后执行微任务队列,再执行宏任务队列。
是不是清晰啦!
这种东西总是会忘,所以想记录一下,总结的可能不太好,欢迎大家指点哈~