check 阶段的 setImmediate 在 poll 阶段的 readFile 之前执行
来源:7-3 从 libuv 源码来理解 Event Loop 的 6 个阶段
ShineTech
2018-02-09
我的是 mac 环境 node 8.9.3, 代码与老师一致,但是打印的执行顺序中,属于第三阶段check的setImmediate 在 属于 第二阶段IO操作的readFile 之前执行。。。这就让我很困惑了。
const { readFile } = require('fs');
const EventEmitter = require('events');
const eve = new EventEmitter();
eve.on('hi', () => {
console.log('hi')
})
setTimeout(() => {
console.log('exec the 1st setTimeout timer')
}, 0)
setTimeout(() => {
console.log('exec the 2nd setTimeout timer')
}, 50)
setTimeout(() => {
console.log('exec the 3rd setTimeout timer')
}, 100)
readFile('./package.json', 'utf-8', data => {
console.log('exec the 1st read file')
})
readFile('./package.json', 'utf-8', data => {
console.log('exec the 2nd read file')
})
setImmediate(() => {
console.log('exec the 1st setImmediate')
})
Promise.resolve().then(() => {
process.nextTick(() => {
console.log('exec the 2nd nextTick')
})
eve.emit('hi')
console.log('exec the 1st promise')
})
.then(() => {
console.log('exec the 2nd promise')
})
process.nextTick(() => {
console.log('exec the 1st nextTick')
})
写回答
2回答
-
这个结果不一样的原因,在于 readfile 这里的处理,readfile 也就是 IO 是不稳定的,执行时间不等,导致它如果没 ready,那么timer 后就会进入到 check 执行 setImmediate,就是你这种结果,如果 IO ready,那么就是视频中的效果,这就是 Nodejs 里面 IO 魔性的地方,你可以把这个文件放到 /test 目录下,然后把 ./package.json 路径改成 ../package.json,多执行几次,会发现结果并不总是一致的,原因就在于 eventloop 转起来的时候,readfile 是否 ready,timer 是否到期进栈,这两个不确定因素会导致 setImmediate 会不会紧挨着 setTimeout 执行
122018-02-12 -
慕粉3563954
2019-07-30
找到答案了
00
相似问题