Node.js 事件循环(Event Loop)是其非阻塞 I/O 模型的核心。事件循环使得 Node.js 能够处理大量并发连接而不需要为每个连接创建新的线程,从而实现高效的异步编程。

以下是关于 Node.js 事件循环的一些基本概念:

1. 事件循环的阶段(Event Loop Phases):
Node.js 事件循环被划分为不同的阶段,每个阶段执行特定的任务。主要的阶段包括:

  •  timers(定时器): 处理 setTimeout 和 setInterval 的回调函数。

  •  I/O callbacks(I/O 回调): 处理除定时器、close callbacks 之外的几乎所有回调。

  •  idle, prepare(空闲、准备): 仅系统内部使用。

  •  poll(轮询): 处理除了定时器和 I/O 之外的事件。

  •  check(检查): 处理 setImmediate 的回调函数。

  •  close callbacks(关闭回调): 处理一些关闭的回调,例如 socket.on('close', ...)。


2. 事件队列(Event Queue):
每个阶段都有一个对应的事件队列,用于存储即将被执行的回调函数。在一个阶段完成后,事件队列中的回调函数将按照顺序被执行。

3. Microtasks 和 Macrotasks:
Node.js 的事件循环中包含 microtasks 和 macrotasks 两种类型的任务。

  •  Microtasks: 由 process.nextTick 和 Promise 的回调函数组成,它们在当前阶段完成后立即执行。

  •  Macrotasks: 由 timers、I/O callbacks、poll、check 和 close callbacks 组成,它们在事件循环的不同阶段执行。


4. 执行过程:
事件循环在每个阶段执行的顺序如下:

1. 执行当前阶段的所有 macrotasks。
2. 执行所有的 microtasks。
3. 如果事件循环未处于关闭状态,且还有未处理的事件,回到第一步。

5. 示例:
下面是一个简单的例子,演示事件循环的基本流程:
console.log('Start');

setTimeout(() => {
    console.log('Timer callback');
}, 0);

Promise.resolve().then(() => {
    console.log('Promise callback');
});

process.nextTick(() => {
    console.log('nextTick callback');
});

console.log('End');

输出顺序将是: