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

为什么await无关异步操作会导致fs.createReadStream创建的流被读取?

原因说明

这个现象是Node.js文件可读流的内部预取缓冲区机制导致的,和你await的异步代码本身没有关联,只是await操作让出了主线程执行权,让流的内置预读逻辑得以执行:

  • 调用fs.createReadStream()生成流实例时,Node.js底层会自动把一个异步预读任务加入事件循环队列,目标是读取最多highWaterMark(默认值为64KB即65536字节)的数据到流的内部缓冲区,提前为后续消费准备数据,这个逻辑不需要你主动监听data事件、调用read()或者pipe()才触发,流创建完成就会自动排队。
  • 第一次同步打印data.bytesRead时,预读的异步任务还在队列中等待执行,主线程还在跑同步代码,所以输出是0。
  • 执行await操作时,会暂停当前同步逻辑执行,让出主线程给事件循环处理其他待执行的异步任务,此时排队的流预读操作就会被执行,读完64KB数据后更新bytesRead属性,所以2秒后打印的结果就是65536。

解决方案

如果不需要流提前预读,可以用下面两种方式关闭该行为:

  • 创建流时传入highWaterMark: 0配置,直接关闭预取逻辑
const data = fs.createReadStream(filePath, { highWaterMark: 0 });
  • 流创建完成后立即调用pause()方法手动暂停读取
const data = fs.createReadStream(filePath);
data.pause();

两种方案下,无论你await多长时间,bytesRead都会保持为0,直到你主动调用data.resume()、绑定data事件或者调用pipe()方法才会开始读取数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 17:15:07