规则:同一时间只有一个任务在运行,同时运行的过程不能被中途打断
事件队列类型:macrotask queue 和microtask queue
常见的macrotask 和 microtask 如下 :
macrotask queue :
Mouse Event
Keyboard Event
Network Event
HTML Parsing
setTimeout
setInterval
setImmediate
I/O
microtask queue :
DOM mutations
Promise
Object.observe
process.nextTick
从分类对应的事件处理来看,macrotask 处理的是耗时比较长的,而 microtask 处理是耗时短的。奇怪的是这两个词看起来比较像,一个是mac-rotask ,另一个是 mic-rotask 就只差了一个字母, 它们分别对应的单词意思表达为:macrotask(表示宏观的)和microtask(表示微观的)
示例如下 :
console.clear();
console.log('========== START ==========');
Part-1:
var interval = setInterval(() => console.log('setInterval'), 0)
setTimeout(()=>console.log('setTimeout 1'),0)
setTimeout(()=>console.log('setTimeout 2'),0)
Part-2:
setTimeout(() => {
console.log('setTimeout 3')
Promise.resolve()
.then(() => {
console.log('promise 1')
})
.then(() => {
console.log('promise 2')
})
.then(() => {
setTimeout(() => {
console.log('setTimeout 4')
Promise.resolve()
.then(() => {
console.log('promise 3')
})
.then(() => {
console.log('promise 4')
})
.then(() => {
setTimeout(() => {
console.log('setTimeout 5')
Promise.resolve()
.then(() => {
console.log('promise 5')
})
.then(() => {
console.log('promise 6')
})
.then(() => {
clearInterval(interval)
console.log('========== END ==========')
})
}, 10)
})
}, 0)
})
}, 0)
Part-3:
Promise.resolve()
.then(() => {
console.log('promise 7')
})
.then(() => {
console.log('promise 8')
})
console.log('========== CONTINUE ==========')
其逻辑结构如下:
=> START
Part-1:
setInterval
setTimeout
setTimeout
Part-2:
setTimeout
Promise => then
=> then
=> then
=> setTimeout
Promise => then
=> then
=> then
=> setTimeout
Promise => then
then
then
clearInterval
END
Part-3:
Promise => then
=> then
CONTINUE
结果显示如下:
Console was cleared
EventLoop:3 ========== START ==========
EventLoop:60 ========== CONTINUE ==========
EventLoop:49 promise 7
EventLoop:52 promise 8
EventLoop:1 undefined
EventLoop:4 setInterval
EventLoop:9 setTimeout 3
EventLoop:12 promise 1
EventLoop:15 promise 2
2EventLoop:4 setInterval
EventLoop:19 setTimeout 4
EventLoop:22 promise 3
EventLoop:25 promise 4
3EventLoop:4 setInterval
EventLoop:29 setTimeout 5
EventLoop:32 promise 5
EventLoop:35 promise 6
EventLoop:39 ========== END ==========
EventLoop:6 setTimeout 2
EventLoop:5 setTimeout 1
那如果把Part-1移动到Part-3后面结果会是怎么的呢?答案是,保持与上面一致执行过程是怎样控制的?首先要理解上面提到的规则,其次记住事件队列的分类(macrotask和microtask),同时还需要记住对应队列下的事件类型。本文由:北大青鸟学校开发小组提供
- 在一个事件循环周期中一个任务的开始是从 macrotask 队列开始执行的,当一个 macrotask 执行结束后,microtasks 队列中的任务将一个个被执行,在 microtask 执行时还可以加入多个 microtask (事件嵌套处理),直到 microtask 队列清空,然后又回到macrotask继续循环。