理解宏队列与微队列能够让你看懂 js 代码的执行顺序
js代码的执行顺序是从上到下,先执行同步代码,再由宏队列与微队列决定回调函数的执行先后
- 会先执行所有的同步代码,
- 之后在宏队列中想要取出第一个宏任务执行前,会先在微队列中将所有的微任务依次取出全部执行完毕,
- 在微队列里面的所有微任务执行完毕,才会进行下一个宏任务。
宏队列
- 存放在宏队列中执行的回调函数:
- dom事件回调
- ajax回调
- 定时器回调
微队列
- 存放在微队列中执行的回调函数:
- promise回调
- mutation回调
<script type="text/javascript">
setTimeout(() => {
console.log("0") // setTimeout的回调 添加到宏任务
}, 0)
new Promise((resolve,reject)=>{
console.log("1") //同步调用,立即执行
resolve() // 这里调用 resolve 之后就会立即执行.then 的回调
}).then(()=>{
console.log("2") // 这里是第一个回调执行,添加到微任务
new Promise((resolve,reject)=>{
console.log("3") // 这里是第一个微任务执行的代码,所有这里会立即执行
resolve() // 这里调用 resolve 之后就会立即执行.then 的回调
}).then(()=>{
console.log("4") // 这里是第二个回调执行,添加到微任务
}).then(()=>{ // 按照顺序执行,这个异步回调会被缓存,因为 4 还没立即执行
console.log("5") // 这里是第四个回调执行,添加到微任务
})
// 在所有.then 执行后执行下一步
}).then(()=>{
console.log("6") // 这里是第三个回调执行,添加到微任务
})
new Promise((resolve,reject)=>{
console.log("7") //同步调用,立即执行
resolve()
}).then(()=>{
console.log("8")
})
</script>
/*
打印的结果: 1 7 2 3 8 4 6 5 0
宏队列: []
微队列: []
根据 js 代码执行输出顺序是什么:
第一步:先初始化执行同步代码:
console.log("1")
console.log("7")
第二步:将回调区分,将宏任务添加到宏队列中, 将微任务添加到微队列中:
第一步 setTimeout的回调 添加到宏任务 也就是宏队列:[0]
第二步 console.log("2") Promise回调 添加到微队列:[2],但是 .then 还没结束
第三步 console.log("8") Promise回调 添加到微队列:[2, 8],
第四步 这时候初始化执行已经结束,这时候去取微队列的第一个微任务执行,结果:[8]
第五步 在取出 2 这一个微任务执行,执行过程直接 同步打印出 3
第六步 在上一步微任务执行后,又产生新的微任务(console.log("4")):[8, 4]
第七步 4 之后 5 不会立即执行,因为 4 还没从微任务中取出执行,而 6 在前面的所有 .then之后执行回调,添加到微任务中:[8, 4, 6]
第八步 在 6 添加到微队列后,已经没有其他任务,开始执行微队列任务:[4, 6], 再执行:[6]
第九步 在 执行 4 这个微任务之后,就会开始执行之后的回调,将 5 添加到微任务:[6, 5]
第十步 之后执行微队列:[]
第十一步 微队列执行完毕,开始执行宏队列的第一个宏任务
*/