reference:
https://segmentfault.com/a/1190000007710772
http://www.ruanyifeng.com/blog/2014/10/event-loop.html
Macrotask
和Microtask
分一下类:
Macrotask:
setTimeout, setInterval, setImmediate, I/O, UI rendering
Microtask:
process.nextTick, Promises, Object.observer, MutationObserver
之前零零散散地读文章,对nodejs的理解不是很深,所以决定好好跟一下《深入浅出nodejs》,读到事件循环那部分的时候,脑海中浮现出Macrotask
和Microtask
的印象,于是好好整理一下这部分的思路。
这里主要是我自己对Macrotask
和Microtask
的理解,事件循环先处理一个Macrotask
,然后处理Microtask queue
,然后Macrotask
,Microtask queue
循环下去…
画成图也许会好理解一些
task queue:
1.先处理当前Macrotask 3.循环之前的步骤
| |
|Macrotask|Microtask queue|Macrotask|Microtask queue|...
|
|Micro|Micro|Micro|...
|
2.然后处理Microtask queue的第一个,第二个...
对于这个问题
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')
})
// 结果:
// script start
// promise 1
// promise 2
// setInterval
// setTimeout 1
// promise 3
// promise 4
// setInterval
// setTimeout 2
// setInterval <- 这里时有时无,很奇怪,求解答
// promise 5
// promise 6
按照上面的task queue
去理解就不难了
首先在当前栈中运行,输出script start
setInterval
作为Macrotask
插入Macrotask queue
setTimeout
也作为Macrotask
插入Macrotask queue
Promise
作为Microtask
插入Microtask queue
task queue:
1.运行script start 3.setTimeout 1插入
| |
Macro queue: |script start |setInterval|setTimeout 1|
^ |
| 2.setInterval插入
4.promise插入
Micro queue: |promise 1|promise 2|
task queue
也就变成了这样(每行第一个是Macrotask,后面是Microtask queue)
task queue:
|script start|promise 1|promise 2 <- 在这里插入
|setInterval
|setTimeout 1
|...
然后setInterval
回调触发,定时器继续将自己加入到任务中
setInterval
作为Macrotask
插入Macrotask queue
task queue:
|script start|promise 1|promise 2
|setInterval
|setTimeout 1
|setInterval <- 在这里插入
|...
setTimeout 1
回调触发
Promise
作为Microtask
插入Microtask queue
task queue:
|script start|promise 1|promise 2
|setInterval
|setTimeout 1|promise 3|promise 4|then <-在这里插入
|setInterval
|...
后面类推
奇怪的是clearInterval
,setTimeout 2
后的Microtask queue
中应该有一个clearInterval
,所以没有出现setInterval
应该是最完美的结果。
但是它却出现在setTimeout 2
和promise 5
之间,而不是在promise 6
之后,这就非常奇怪了,求大佬解答。