说起js的事件循环机制,那真是我心中的痛。
我一开始理解js的事件循环时候,我理解错了,我把setTimeout理解成了微任务, 从而只要是关于js事件循环,我都理解错了,一直到一个阳光明媚的下午, 我才真正的找到了正确的理解方式。
# 任务队列
每个事件循环都至少有一个宏任务队列(Task Queue)和一个微任务队列(Microtask Queue), 分别压入需要执行的宏任务和微任务。
宏任务: script内的同步代码、setTimeout、setInterval、I/O、rendering、requestAnimationFrame
微任务: process.nextTick、Promise callback、MutationObserver
微任务也是有优先级的
process.nextTick() > Promise.then()
nextTick属于一个特殊API,他会立即执行,然后才会继续执行event loop
setTimeout-0和setImmediate
无法具体确定哪个先执行
但是如果同时处在异步I/O callback里面,setImmediate先执行
# 事件循环
1.主线程执行任务栈内的任务
2.执行任务完毕去检查任务队列,首先会处理掉所有微任务
3.更新render,每次事件循结束浏览器都会更新渲染
4.再去宏任务队列中取出一个事件压入任务栈,开始下一轮循环
事件循环就是重复上述过程
执行顺序
执行macrotask -> js stack空时执行microtask -> UI render -> 开始下一轮循环
# 实例分析
宏任务1 -> 微任务1,微任务2,宏任务2;
微任务1 -> 微任务3,宏任务3,微任务4;
微任务2 -> 宏任务4,微任务5;
宏任务2 -> 微任务6,宏任务5
开始分析:
开始执行宏任务1
已执行队列:宏1
宏任务队列:宏2
微任务队列:微1 微2执行微任务1
已执行队列:宏1 微1
宏任务队列:宏2 宏3
微任务队列:微2 微3 微4执行微任务2
已执行队列:宏1 微1 微2
宏任务队列:宏2 宏3 宏4
微任务队列:微3 微4 微5执行微任务3、4、5
已执行队列:宏1 微1 微2 微3 微4 微5
宏任务队列:宏2 宏3 宏4
微任务队列:执行宏任务2
已执行队列:宏1 微1 微2 微3 微4 微5 宏2
宏任务队列:宏3 宏4 宏5
微任务队列:微6执行微任务6
已执行队列:宏1 微1 微2 微3 微4 微5 宏2 微6
宏任务队列:宏3 宏4 宏5
微任务队列:执行宏任务3、4、5
已执行队列:宏1 微1 微2 微3 微4 微5 宏2 微6 宏3 宏4 宏5
宏任务队列:
微任务队列:结束
# 再看一个
console.log('1');
setTimeout(function() {
console.log('2');
process.nextTick(function() {
console.log('3');
})
new Promise(function(resolve) {
console.log('4');
resolve();
}).then(function() {
console.log('5')
})
console.log('t')
})
process.nextTick(function() {
console.log('6');
})
new Promise(function(resolve) {
console.log('7');
resolve();
}).then(function() {
console.log('8')
})
setTimeout(function() {
console.log('9');
process.nextTick(function() {
console.log('10');
})
new Promise(function(resolve) {
console.log('11');
resolve();
}).then(function() {
console.log('12')
})
})
执行log1 log7
已执行:1 7
宏队列:s2345t s9_10_11_12
微队列:p6 t8执行微任务p6 t8
已执行:1 7 6 8
宏队列:s2345t s9_10_11_12
微队列:执行宏任务s2345t
已执行:1 7 6 8 2 4 t
宏队列:s9_10_11_12
微队列:p3 t5执行微任务p3 t5
已执行:1 7 6 8 2 4 t 3 5
宏队列:s9_10_11_12
微队列:执行宏任务s9_10_11_12
已执行:1 7 6 8 2 4 t 3 5 9 11
宏队列:
微队列:p10 t12执行微任务p10 t12
已执行:1 7 6 8 2 4 t 3 5 9 11 10 12
宏队列:
微队列:结束
← 防抖和节流 axios和ajax →