← 返回目录

第 1 卷

第 1 / 12 卷日期:

深入解析 Node.js:事件循环与非阻塞 I/O

一、什么是Node.js?它是如何工作的?

  1. 什么是Node.js

你可以将Node.js理解为一个基于Chrome V8 JavaScript引擎构建的服务器端运行环境,它并非编程语言(仍使用JavaScript),也非框架,核心作用是让JavaScript脱离浏览器环境,能够在服务器端执

行文件读写、网络请求、数据库操作等后端开发任务。Node.js具有轻量、高效的特性,尤其适用于高并发的I/O密集型应用(如API接口、实时聊天、数据流处理等)。

  1. Node.js的工作原理
  2. 核心依赖:基于Chrome V8引擎(高性能JavaScript解释器,将JS代码编译为机器码执行,保证运

行效率),同时封装了libuv库(跨平台异步I/O库,提供事件循环、异步网络/文件操作等核心能力)。

  1. 单线程+事件驱动:Node.js主线程是单线程的,不会为每个请求创建新线程,而是通过事件驱动模

型处理并发请求⸺所有异步操作(如文件读取、网络请求)都会被委托给底层线程池(由libuv管理),主线程仅负责监听事件完成后的回调函数,避免了线程切换的开销。

  1. 执行流程:JS代码由V8引擎解析执行,遇到异步I/O操作时,Node.js将其移交libuv线程池处理,

主线程继续执行后续同步代码;当异步操作完成后,libuv会将对应的回调函数放入事件队列,等待事件循环取出并交由V8引擎执行。

二、Node.js中的全局对象有哪些?举例说明它们的用途

Node.js的全局对象无需通过 require() 导入,可在所有模块中直接访问,核心全局对象及用途如下:

1.global:Node.js的顶层全局对象(类似浏览器中的 window),所有全局变量(除了模块内的局部变量)都是 global 的属性。

  • 用途:定义全局可访问的变量或方法。

◦ 示例:

Code block

1// 在任意模块中定义全局变量 2global.userName = "张三";

3// 在其他模块中可直接访问 4console.log(userName); // 输出:张三

  • 用途:开发调试、日志记录。

◦ 示例:

Code block

1console.log("普通日志信息"); // 普通输出 2console.error("错误信息提示"); // 错误输出(通常显示为红色)

3console.table([{name: "张三"}, {name: "李四"}]); // 以表格形式输出数据

3.process:提供当前Node.js进程的信息和控制能力,是与操作系统交互的核心对象。

  • 用途:获取进程参数、环境变量、退出进程、监听进程事件等。

◦ 示例:

Code block

1console.log(process.pid);//输出当前进程ID
2console.log(process.env.NODE_ENV);//输出环境变量(如开发环境/生产环境)
3process.exit(0);//正常退出进程(参数0表示正常退出,非0表示异常退出)
4. Buffer:用于处理二进制数据(Node.js原生不支持直接操作二进制数据,Buffer是核心解

决方案)。

  • 用途:文件读写、网络数据传输、加密解密等场景中的二进制数据处理。

◦ 示例:

Code block

1// 创建一个Buffer实例

2const buf = Buffer.from("Hello Node.js", "utf8");
3console.log(buf.toString("utf8"));//转换为字符串输出:Hello Node.js
4console.log(buf.length);//输出Buffer的字节长度
5. setTimeout/setInterval/setImmediate:定时器相关全局方法,用于延迟或周期性

执行函数。

  • 用途:延迟执行任务、定时轮询、立即执行异步任务等。

◦ 示例:

6setImmediate(() => console.log("立即异步执行"));

三、Node.js的事件循环机制,它如何处理异步操作?

  1. 事件循环(Event Loop)的核心定义

事件循环是Node.js实现非阻塞异步编程的核心机制,它是一个无限循环的流程,负责监听事件队列、取出异步操作完成后的回调函数,并将其交由V8引擎主线程执行,从而让单线程的Node.js能够处理大

量并发异步请求。

  1. 事件循环的阶段划分(从内到外,按执行优先级排序)

Node.js的事件循环分为6个阶段,每个阶段都会处理对应的回调队列,只有当前阶段的队列处理完毕(或达到最大执行数),才会进入下一个阶段:

  1. timers(定时器阶段):处理 setTimeout 和 setInterval 的回调函数(延迟时间到期后的

回调)。

  1. pending callbacks(待定回调阶段):处理少数系统级回调(如TCP连接错误的回调)。
  2. idle, prepare(空闲/准备阶段):内部使用,开发者无需关注。
  3. poll(轮询阶段):核心阶段,负责监听I/O事件(文件I/O、网络I/O等),并处理对应的回调;若

没有待处理的回调,会在此阶段阻塞等待新的I/O事件。

  1. check(检查阶段):处理 setImmediate 方法注册的回调函数。
  2. close callbacks(关闭回调阶段):处理关闭事件的回调(如 socket.on('close',

callback))。

  1. 事件循环处理异步操作的流程
  2. 同步代码优先执行:Node.js启动后,先执行当前模块的同步代码,遇到异步操作(如

setTimeout、文件读取),不会阻塞主线程,而是将异步任务委托给底层libuv线程池(或系统内核)处理,同时将回调函数注册到对应的事件队列中。

  1. 进入事件循环:同步代码执行完毕后,主线程进入事件循环,按照上述6个阶段的优先级,依次处

理每个阶段的回调队列。

  1. 回调执行与循环往复:每个阶段的回调队列处理完毕后,进入下一个阶段;当所有6个阶段处理完

毕后,事件循环会再次从头开始(timers阶段),形成无限循环,直到没有待处理的回调和进程退出。

  1. 微任务队列的优先级:在每个事件循环阶段切换之前,会先处理所有微任务队列中的回调
全站分卷索引 · 12 卷
  1. 1第 1 卷
  2. 2第 2 卷
  3. 3第 3 卷
  4. 4第 4 卷
  5. 5第 5 卷
  6. 6第 6 卷
  7. 7第 7 卷
  8. 8第 8 卷
  9. 9第 9 卷
  10. 10第 10 卷
  11. 11第 11 卷
  12. 12第 12 卷