Node.js事件循环I/O callback与poll阶段差异及理解求证
Hey there! Let's untangle this confusion around the I/O callbacks and poll phases in Node.js's event loop—this is a super common sticking point, so let's break it down with your fs.readFile example.
First, let's walk through the full flow of fs.readFile
When you run code like this:
fs.readFile('/my/file.txt', (err, data) => { console.log('File read complete:', data); });
Here's what actually happens step by step:
- Node hands off the I/O request to the OS kernel: The moment you call
fs.readFile, Node doesn't wait around—it sends the file read request to your computer's operating system kernel, which is optimized for handling I/O operations like disk reads. - Kernel works in the background: The kernel reads the file from disk while Node's event loop continues processing other tasks (like running synchronous code, handling other events, etc.). This is why Node is "non-blocking" for I/O.
- Kernel notifies Node when done: Once the kernel finishes reading the file, it sends a signal back to Node. Node then adds your
fs.readFilecallback to the poll queue. - Poll phase executes the callback: When the event loop reaches the poll phase, it checks if there are callbacks in the poll queue. If yes, it executes them—this is when your
console.logruns.
Key differences between I/O Callbacks and Poll phases
Let's clarify what each phase actually does, since this is where your confusion lies:
I/O Callbacks (aka Pending Callbacks) phase
This is a specialized phase for handling leftover or system-level I/O callbacks that couldn't be processed in the previous loop iteration. Examples include:
- Error callbacks for certain system operations (like a TCP connection receiving an
ECONNREFUSEDerror) - Callbacks from older, deprecated Node.js APIs (you won't encounter these often in modern code)
Most of the everyday I/O callbacks you work with (like fs.readFile, HTTP request handlers, database query callbacks) do not run here.
Poll phase
This is the workhorse phase of the event loop for most I/O tasks. It has two main jobs:
- Execute callbacks from the poll queue: This includes all the regular I/O completion callbacks we mentioned (file reads, network responses, etc.).
- Wait for new I/O events if the queue is empty: If there are no callbacks to run, the event loop will block here and wait for new I/O events to arrive (like a new HTTP request coming in, or a file finish reading), then add their callbacks to the queue and execute them immediately.
Correcting your misunderstandings
Let's address the specific questions you had:
- ❌ "poll阶段接收读取文件的I/O指令" — No, the I/O request is sent to the kernel the moment you call
fs.readFile, not when the event loop reaches the poll phase. - ❌ "文件读取操作是在poll阶段进行的" — No, the file read is handled entirely by the OS kernel in the background, parallel to Node's event loop. The poll phase only handles the callback once the read is done.
- ❌ "fs.readFile()的回调添加到I/O callback阶段" — No, this callback goes to the poll queue and runs in the poll phase. The I/O callbacks phase is for edge-case, leftover callbacks, not regular file reads.
内容的提问来源于stack exchange,提问作者Prem

