0033. Node.js 的工作原理概述
1. 📒 概述
- 本节大致内容:
- 事件驱动
- 单线程
- 非阻塞 I/O
- 事件循环
- 模块化设计
- 本节笔记主要会对 Node.js 原理中的这些部分做一个简单的说明,其中的每个点展开都是不小的篇幅,后续学到相关内容的时候,再作更为详细的说明。
2. 📒 事件驱动
- Node.js 使用事件驱动模型,将 I/O 操作作为事件响应处理,而非阻塞操作。
- 这种方式使得事件函数能够快速执行,并支持高效的错误处理。
- 通过异步非阻塞的方式访问外部资源(如文件系统、数据库、网络等),Node.js 能够高效处理海量并发请求,显著提升应用程序的吞吐量。
3. 📒 单线程
- Node.js 采用单线程模型,使用轻量级线程即可处理大量请求。
- 相较于多线程模型,单线程避免了线程竞争问题,提升了程序的稳定性。
- 所有的 I/O 操作都被放入事件队列中,Node.js 会依次处理这些事件。
- 大多数服务器端应用的主要任务是接收请求并将其交给其他服务处理(如读取数据库),然后等待结果返回。因此,Node.js 的单线程模型非常适合这种场景。
- 单线程模型避免了创建、销毁线程以及在线程间切换的开销和复杂性。
4. 📒 非阻塞 I/O
- 在传统 I/O 操作中,当进行数据读取或写入时,程序会被阻塞,直到操作完成才能继续下一步。
- Node.js 的所有 I/O 操作都是非阻塞的,当某个 I/O 操作发生时,不会等待其完成,而是直接回调相应的函数。
- 这种机制实现了对外部资源的高效访问,提升了性能。
5. 📒 事件循环
- Node.js 使用事件循环机制来处理任务队列中的事件,确保高效的并发处理能力。
- 事件循环的主要工作阶段包括:
- 计时器:处理由
setTimeout()
和setInterval()
设置的回调。 - 回调:运行挂起的回调函数。
- 轮询:检索传入的 I/O 事件,并运行与 I/O 相关的回调。
- 检查:在轮询阶段完成后立即运行回调。
- 关闭回调:处理关闭事件和相关回调。
- 计时器:处理由
- 尽管 JavaScript 在 Node.js 中运行在单线程环境,但底层通过线程池(由 libuv 实现)完成异步 I/O 操作。
- libuv 提供了跨平台的统一调用接口,屏蔽了不同平台的差异性,确保 Node.js 的跨平台兼容性。
6. 📒 模块化设计
- 在 Node.js 中,采用了一种模块化的设计方式,按照功能模块将代码拆分成多个文件,使用 require 函数引入,从而提高了代码的复用率,同时也增强了代码的可维护性。
- 另外,Node.js 提供了许多内置模块,如 http 模块、fs 模块等,能够帮助开发者快速搭建 Web 应用服务。