事件循环详解

JS事件循环

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
console.log('script start');

setTimeout(function () {
console.log('setTimeout');
}, 0);

Promise.resolve()
.then(function () {
console.log('promise1');
})
.then(function () {
console.log('promise2');
});

console.log('script end');

可以试一下他的输出顺序。

答案

1
2
3
4
5
script start
script end
promise1
promise2
setTimeout

在微软的Edge浏览器,和火狐40,Safari 8.0.8中setTimeout会比promise1promise2先输出,出现这种情况真是奇了TML怪,因为Firefox39和Safari8.0.7一直都是正确的。

原因

想要了解事件循环,需要先了解事件循环是如何处理宏任务,与微任务。

每一个线程有自己的事件循环机制。所以每一个web worker 都是独立执行的,但是在同一个域名的窗口是同用一个事件循环,所以他们才可以同步通信。事件循环顺序执行队列任务。

Nodejs事件循环

Nodejs的事件循环与浏览器的事件循环机制并不相同,Nodejs虽然使用Chrome v8作为JS解释引擎,但是异步控制的实现是在libuv库中。

来个栗子

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

setTimeout(() => {
console.log('timer1')
Promise.resolve().then(function(){
console.log('promise1')
})
},0)

setTimeout(() => {
console.log('timer2')
Promise.resolve().then(function()
{
console.log('promise2')
})
},0)

Promise.resolve().then(function(){
console.log('promise3')
})

console.log('end')

// start,
// end,
// promise3,
// timer1,
// timer2,
// promise1,
// promise2

未完待续。。。

参考链接

https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/

https://mp.weixin.qq.com/s/hE-tK_PbSYkMms8P9b2H7A

https://nodejs.org/zh-cn/docs/guides/event-loop-timers-and-nexttick/