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

Node.js事件循环中setTimeout与fs.readFile执行顺序疑问

Node.js事件循环:为什么fs.readFile回调先于setTimeout执行?

先看你的代码:

const fs = require("fs");

setTimeout(() => {
  console.log("timeout");
}, 1000);

fs.readFile("read.txt", "utf8", (err, data) => {
  console.log(data);
});

原因核心在于定时器到期时间和事件循环执行时机的关系:

  1. 同步代码执行阶段:

    • 调用setTimeout时,Node会标记这个回调需在1000ms后执行,但不会立刻将其放入待执行的timers队列,要等时间真正到期后,才会把回调移进队列。
    • 调用fs.readFile时,Node会把文件读取任务交给后台线程池处理,同步代码很快执行完毕,事件循环开始运转。
  2. 事件循环第一轮检查:

    • 首先进入Timers阶段:此时距离setTimeout被调用还没到1000ms,定时器未到期,这个阶段没有可执行的回调,直接跳过。
    • 接着进入I/O回调阶段:后台线程已经完成了小文件read.txt的读取,对应的回调已被放入I/O队列,事件循环立刻执行这个回调,输出hello。
  3. 后续事件循环:
    事件循环会反复遍历各个阶段,直到1000ms到期后,下一次进入Timers阶段时,才会发现setTimeout的回调已可执行,进而输出timeout。

简言之:读取小文件的耗时远小于1000ms,在定时器到期前,事件循环已经跑完多轮,并在I/O阶段执行了文件读取的回调。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 08:37:40