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

Node.js中Readable stream在Express.js内用pipe返回响应失效求解

Node.js 流发送数据问题修复方案

核心问题原因

你写的自定义可读流没有标记数据传输结束,且不符合流的按需拉取设计逻辑,导致流卡住、响应无法正常结束。

具体问题点

  • 所有数据push完成后没有执行stream.push(null),这是可读流标记数据全部传输完成的必要操作,缺少这行的话end事件永远不会触发,pipe方法也不知道流已经传输完成,会一直挂起响应。
  • 传入Readable构造函数的read方法为空实现,虽然这不是直接导致报错的原因,但提前把所有数据全量推入流内部缓冲区的写法会丢失流分批处理、控制内存占用的优势,数据量大时还会导致内存溢出。

修复后代码

更推荐的pipe版本(符合流设计规范)

const { Readable } = require("stream")

app.get('/test', (req,res) => {
  const month = ['jan','feb','mar','apr','may','jun','jul'];
  let dataIndex = 0
  const stream = new Readable({
    read(size) {
      // 所有数据读取完成,标记流结束
      if (dataIndex >= month.length) {
        this.push(null)
        return
      }
      // 按需推送数据
      this.push(month[dataIndex], 'utf8')
      dataIndex++
    }
  });
  stream.setEncoding('utf8')
  stream.pipe(res)  
})

兼容你原有写法的修复版本

如果你坚持要提前把所有数据推入缓冲区,只需要补加标记流结束的代码即可:

const { Readable } = require("stream")

app.get('/test', (req, res) => {
  const month = ['jan','feb','mar','apr','may','jun','jul'];
  const stream = new Readable({read(size){}});
  stream.setEncoding('utf8')
      
  for (let m of month) {
    stream.push(m)
  }
  // 新增这行,标记可读流没有更多数据
  stream.push(null)
       
  stream.on('data', (data) => {
    console.log(data)
    res.write(data,'utf8')
  })
   
  stream.on('end',() => {
    res.end();
  })
})

额外说明

你的原代码中路由函数加了async关键字但没有用到异步逻辑,不会影响运行,不需要的话可以删除避免不必要的误解。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 05:06:03