事件队列详解
基础执行顺序
先走主进程,再走微任务,再走宏任务。nodejs中,微任务只能有1000个,多出的只能下次事件循环再执行。
宏任务:setTimeout,setInterval,requestAnimationFrame
微任务:Promise,queueMicrotask
宏任务与微任务嵌套
宏任务套微任务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20console.log(1)
setTimeout(()=>{
console.log('宏任务1')
queueMicrotask(()=>{
console.log('微任务2')
})
})
setTimeout(()=>{
console.log('宏任务2')
queueMicrotask(()=>{
console.log('微任务3')
})
})
queueMicrotask(()=>{
console.log('微任务1')
})
console.log(2)
// 被宏任务嵌套的微任务,在宏任务后执行,并不会有插队现象
// 1 2 微任务1 宏任务1 微任务2 宏任务2 微任务3微任务嵌套宏任务
1 | console.log(1) |
微任务嵌套微任务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16console.log(1)
queueMicrotask(()=>{
console.log('微任务1')
queueMicrotask(()=>{
console.log('微任务2')
})
})
queueMicrotask(()=>{
console.log('微任务3')
})
console.log(2)
// 1 2 微任务1 微任务3 微任务2宏任务套宏任务
1
2
3
4
5
6
7
8
9
10
11
12
13console.log(1)
setTimeout(()=>{
console.log('宏任务1')
setTimeout(()=>{
console.log('宏任务2')
})
})
setTimeout(()=>{
console.log('宏任务3')
})
console.log(2)
// 1 2 宏任务1 宏任务3 宏任务2
Promise不一样的事件队列
- then是个黑盒子
1
2
3
4
5
6
7
8
9
10
11
12console.log(1)
Promise.resolve('x').then(()=>{
console.log('微任务1')
Promise.resolve('x').then(()=>{
console.log('微任务2')
})
}).then(()=>{
console.log('微任务3')
})
console.log(2)
// then会导致事件插队,会使微任务2插队到微任务3前面(浏览器和Node11以上会插队)
// 1 2 微任务1 微任务2 微任务3 - resolve也是个黑盒子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52Promise.resolve('x').then(()=>{
console.log(1)
}).then(()=>{
console.log(3)
}).then(()=>{
console.log(5)
}).then(()=>{
console.log(7)
}).then(()=>{
console.log(9)
})
Promise.resolve('x').then(()=>{
console.log(2)
}).then(()=>{
console.log(4)
}).then(()=>{
console.log(6)
}).then(()=>{
console.log(8)
}).then(()=>{
console.log(10)
})
// then的实现就是如此,不知道原理
// 1 2 3 4 5 6 7 8 9 10
Promise.resolve('x').then(()=>{
console.log(1)
}).then(()=>{
console.log(3)
return Promise.resolve(3,5)
}).then(()=>{
console.log(5)
}).then(()=>{
console.log(7)
}).then(()=>{
console.log(9)
})
Promise.resolve('x').then(()=>{
console.log(2)
}).then(()=>{
console.log(4)
}).then(()=>{
console.log(6)
}).then(()=>{
console.log(8)
}).then(()=>{
console.log(10)
})
// 单独调用resolve,一个resolve推迟两个时序,resolve实现就是如此,不知道原理
// 1 2 3 4 6 8 5 10 7 9
NodeJs的事件循环
NodeJs单独的任务
宏任务:rs.readFile(path,fn)
微任务:setImmediate,process.nextTick(在)NodeJs事件循环有6个步骤
[1] timers : 处理setTimeout
[2] I/O callbacks
[3] 准备阶段
[4] poll(轮询阶段):访问操作系统的相关准备是否完毕
[5] check : 处理setImmediate
[6] close callbackssetTimeout和setImmediate
1 | setTimeout(()=>{ |
答案不唯一,事件循环是用C++写的,应用是JS的,有可能是C++先启动的,也有可能是JS先启动,说白了,这两件事情没关系
1 | setTimeout(()=>{ |