# 14.宏任务与微任务
# 宏任务:
# | 浏览器 | Node |
---|---|---|
I/O | ✅ | ✅ |
setTimeout | ✅ | ✅ |
setInterval | ✅ | ✅ |
setImmediate | ❌ | ✅ |
requestAnimationFrame | ✅ | ❌ |
# 微任务:
# | 浏览器 | Node |
---|---|---|
process.nextTick | ❌ | ✅ |
MutationObserver | ✅ | ❌ |
Promise.then catch finally | ✅ | ✅ |
js先把宏任务放进宏任务队列里,再把微任务放进微任务队列里,执行的时候先执行宏任务队列里的一个任务(通常是全局作用域中的代码),再把微任务队列里的所有任务执行完毕,再去执行宏任务队列里的一个任务,再去把微任务清空......一直交替进行
# 1. macroTask(宏任务)
所有同步JS代码、setTimeout(),setInterval()的任务都是宏任务,它们会被加进Event Queue(宏任务的事件队列)
# 2. microTask(微任务)
所有promise和process.nextTick()都是微任务,它们也会被加进Event Queue(微任务的事件队列)
# 3. 面试题1
console.log('script start')
setImmediate(()=>{
console.log('setImmediate')
})
setTimeout(()=>{
console.log('setTimeout');
process.nextTick(function() {
console.log('process.nextTick2');
});
})
process.nextTick(function() {
console.log('process.nextTick1');
});
Promise.resolve().then(()=>{
console.log('promise1')
}).then(()=>{
console.log('promise2')
})
console.log('script end')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
请问执行顺序? 若是刚启动nodejs,则是:
- script start
- script end
- process.nextTick1
- promise1
- promise2
setTimeout
- process.nextTick2
setImmediate
若不是刚启动,则是:
- script start
- script end
- process.nextTick1
- promise1
- promise2
setImmediate
setTimeout
- process.nextTick2
所以,先执行宏任务(所有同步的js代码),再清空微任务队列(promise1、promise2),再执行宏任务。若是刚启动nodejs,则setTimeout在前,不然都是set Immediate在前
# 4. 面试题2
setTimeout(function(){
console.log('1')
});
new Promise(function(resolve){
console.log('2');
}).then(function(){
console.log('3')
});
console.log('4');
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
顺序为:2 4 3 1 因为2是同步代码