Node.js 的事件循环是其非阻塞 I/O 架构的核心,它使得 Node.js 能够处理大量并发连接,而不会因为 I/O 操作而阻塞线程。事件循环的工作机制如下:
定时器(Timers):这个检查点用于处理 setTimeout 和 setInterval 的回调。
I/O 事件(I/O Events):这个检查点处理除了定时器之外的所有 I/O 事件,比如文件读写、网络请求等。
关闭的回调(Close Callbacks):这个检查点执行一些资源清理工作,比如 socket 或文件流的关闭。
暂停的回调(SetImmediate):这个检查点处理所有的 setImmediate 调用,它们会在当前事件循环结束时执行。
检查点(Poll):这个检查点负责处理 I/O 事件,如果上一个轮次中没有 I/O 事件,那么 Node.js 会在这里等待 I/O 事件。
轮询(Check):这个检查点处理 setImmediate 之外的 nextTick 调用。
执行 I/O 回调(Callbacks):这个检查点执行几乎所有的 I/O 回调,比如读取文件、请求数据库等。
事件循环的工作流程大致如下:
Node.js 启动时,事件循环开始运行。
当一个 I/O 请求被发出时(例如读取文件或发送网络请求),Node.js 将请求发送到操作系统,然后立即继续执行其他代码,不会等待 I/O 操作完成。
操作系统在后台处理 I/O 请求,完成后会通知 Node.js。
Node.js 接收到通知后,会将相应的回调函数放入事件循环的待执行队列中。
事件循环检查各个检查点,依次执行回调函数。
当事件循环的当前迭代完成所有检查点后,会开始下一个迭代。
事件循环的关键在于它允许 Node.js 在等待 I/O 操作完成的同时继续执行其他代码,这样可以提高应用程序的吞吐量和响应性。这种模型也意味着 Node.js 应用程序通常是单线程的,但通过事件循环和非阻塞 I/O,它们可以高效地处理并发操作。