一道事件循环列面试题

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
console.log('script start')

const interval = setInterval(() => {
console.log('setInterval')
}, 0)

setTimeout(() => {
console.log('setTimeout 1')
Promise.resolve().then(() => {
console.log('promise 3')
}).then(() => {
console.log('promise 4')
}).then(() => {
setTimeout(() => {
console.log('setTimeout 2')
Promise.resolve().then(() => {
console.log('promise 5')
}).then(() => {
console.log('promise 6')
}).then(() => {
clearInterval(interval)
})
}, 0)
})
}, 0)

Promise.resolve().then(() => {
console.log('promise 1')
}).then(() => {
console.log('promise 2')
})

最终结果

safari,ff,nodejs与此结果一致,chrome某些版本会多出现一次interval(promise4后)

1
2
3
4
5
6
7
8
9
10
11
script start
promise1
promise2
setInterval
setTimout1
promise3
promise4
setInterval
timeout2
promise5
promise6

参考链接

https://stackoverflow.com/a/30910084
https://blog.risingstack.com/node-js-at-scale-understanding-node-js-event-loop/

分析步骤

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
52
53
54
55
56
57
/// whole script tag as task,start exec
///
/// script start log
///
/// task queue: setInterval,setTimeout1
/// micro queue : [then1,then2]
///
/// start exec microqueue,执行完所有micro queue再执行下一次task queue
/// promise1 log
/// promise2 log
///
/// task queue: setInterval,setTimeout1
/// micro queue : []

/// 开始执行setInterval
/// setInterval log
///
/// task queue: setTimeout1,setInterval
/// micro queue : []

// micro queue 为空,继续下一轮task queue,执行setTimout1
// setTimout1 log
//
/// task queue: setInterval
/// micro queue : [then3,then4,then45(第三个)]
///
/// 开始执行micro queue
/// promise3 log
/// promise 4 log
/// 将timeout push到taskqueue
///
/// task queue: setInterval,setTimeout2
/// micro queue : []

//开始执行task
//
//setInterval log
//

/// task queue: setTimeout2,setInterval
/// micro queue : []

// micro为空,继续执行task, timeout2出
// timeout2 log
// 将then5 then6 thenlast push到micro queue
//
/// task queue: setInterval
/// micro queue : [then5 then6 thenlast]

//开始执行micro queue
//
// promise5 log
// promise6 log
// then last clearInterval
//
/// task queue: []
/// micro queue : []