Node.js Event Loop各阶段讲解
Node.js的Event Loop是其异步非阻塞I/O的关键之一,它被设计成高效运行大量并发请求的系统,各个阶段的功能也可以让我们更好地理解Node.js的运行机制。
各阶段讲解
Node.js的Event Loop包含6个阶段,按顺序分别是:
timers
:处理定时器操作;pending callbacks
:执行一些系统操作的回调;idle, prepare
:内部使用,用于修复它们两个之间的调用顺序;poll
:对I/O事件进行轮询;check
:执行setImmediate API的回调;close callbacks
:执行一些关闭事件的回调。
下面我们详细讲解每个阶段:
timers
这个阶段会检查是否有定时器满足条件,如果有,就会执行这些定时器的回调函数。setTimeout和setInterval是基于这个阶段的。需要注意的是,执行定时器回调是有顺序的。
pending callbacks
这个阶段会执行一些系统操作的回调,如TCP错误的回调。
poll
这个阶段是Event Loop中最常用的一个阶段,用于轮询I/O事件并执行对应的回调。在进入此阶段时,如果定时器阶段没有定时器需要执行,会发生以下两件事之一:
- 如果poll队列为空,Node.js 会阻塞在这个阶段等待I/O事件的触发;
- 如果poll队列不为空,Node.js 会处理每一个事件,直到poll队列为空或达到系统限制。
如果事件到达了其poll事件队列,而且poll已经被添加到活动的定时器列表中,Node.js会在第一个可用的时间运行它的处理程序。因此,poll阶段和定时器阶段可以相互交错。如果在进入此阶段时已经有定时器需要执行,它们将直接转到定时器阶段。
check
这一阶段主要是执行setImmediate() API的回调。在前面的示例中可以看到,setImmediate() 回调优先于 I/O 事件执行。例如:
setImmediate(() => {
console.log('Set Immediate');
});
fs.readFile('./example.txt', () => {
console.log('I/O Callback');
});
console.log('Hello World');
上面的代码会首先执行 'Hello World',然后执行I/O Callback,最后执行Set Immediate。
close callbacks
这个阶段执行一些关闭事件的回调函数,例如socket.on('close', ...)。
示例说明
以上就是Node.js Event Loop各阶段的详细讲解。下面我们来看两个示例:
示例1
setImmediate(() => {
console.log('Set Immediate');
});
setTimeout(() => {
console.log('Set Timeout Timer');
}, 0);
console.log('Hello World');
这个示例中,Node.js 先完成当前运行的同步代码,输出 "Hello World",接着进入 timers
阶段,但此阶段中没有定时器需要执行,于是 Node.js 进入 poll
阶段并阻塞等待。由于示例中发生了跨阶段的定时,因此事件触发时先执行 check
阶段的 setImmediate
回调,然后执行 timers
阶段的 setTimeout
回调,输出 "Set Timeout Timer",最后输出 "Set Immediate"。
示例2
const fs = require('fs');
fs.readFile('./example.txt', () => {
setTimeout(() => {
console.log('Set Timeout Timer');
}, 0);
setImmediate(() => {
console.log('Set Immediate');
});
console.log('I/O Callback');
});
console.log('Hello World');
这个示例中,Node.js 先完成当前运行的同步代码,输出 "Hello World",接着进入 timers
阶段,但此阶段中没有定时器需要执行,于是 Node.js 进入 poll
阶段。在 poll
阶段中,Node.js 处理 fs.readFile
事件,并执行回调。由于示例中发生了跨阶段的定时,因此事件触发时先执行 check
阶段的 setImmediate
回调,然后执行 timers
阶段的 setTimeout
回调,输出 "Set Timeout Timer",最后输出 "Set Immediate"。
以上两个示例可以帮助读者更好地理解 Node.js 的 Event Loop 的执行流程。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Node.js Event Loop各阶段讲解 - Python技术站