You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js事件循环中pending callbacks与poll阶段的差异解析

区分Node.js事件循环的pending callbacks与poll阶段I/O回调

核心差异

pending callbacks阶段负责处理延迟到下一次循环迭代的I/O回调,这类回调多是系统级操作的遗留回调;poll阶段则是处理新产生的I/O事件回调,也是绝大多数常规异步I/O回调的执行场所。


示例1:pending callbacks阶段的场景(TCP连接错误回调)

const net = require('net');

// 尝试连接一个不存在的本地端口
const socket = new net.Socket();
socket.connect(8123, 'localhost', () => {
  console.log('连接成功');
});

socket.on('error', (err) => {
  console.log('触发error回调:', err.message);
});

// 同步代码优先执行
console.log('同步代码执行');

执行流程说明:

  1. 同步代码先运行,输出 同步代码执行。
  2. TCP连接尝试失败时,对应的错误回调不会立即在当前循环的poll阶段处理,而是被延迟到下一次循环的pending callbacks阶段执行。
  3. 事件循环流转到pending callbacks阶段时,才会触发error回调,输出类似 触发error回调:connect ECONNREFUSED 127.0.0.1:8123 的内容。

示例2:poll阶段的场景(文件读取回调)

const fs = require('fs');

// 异步读取本地文件
fs.readFile('./example.txt', 'utf8', (err, data) => {
  if (err) throw err;
  console.log('文件读取完成:', data);
});

// 同步代码优先执行
console.log('同步代码执行');

执行流程说明:

  1. 同步代码先运行,输出 同步代码执行。
  2. Node.js在poll阶段会等待文件I/O操作完成,一旦读取完成,对应的回调会立即在当前poll阶段执行,输出 文件读取完成:[文件内容]。

对比示例:两个阶段的执行顺序

const net = require('net');
const fs = require('fs');

// 触发pending callbacks的回调
const socket = new net.Socket();
socket.connect(8123, 'localhost');
socket.on('error', () => console.log('pending callbacks阶段:TCP错误回调'));

// 触发poll阶段的回调
fs.readFile('./example.txt', 'utf8', () => console.log('poll阶段:文件读取回调'));

console.log('同步代码执行');

预期输出顺序(假设example.txt存在且读取无异常):

同步代码执行
poll阶段:文件读取回调
pending callbacks阶段:TCP错误回调

原因:

poll阶段会优先处理新产生的I/O事件回调,等poll阶段的任务处理完后,事件循环才会进入pending callbacks阶段处理延迟的遗留回调。

内容的提问来源于stack exchange,提问作者MaximPro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 19:45:43