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

如何在Node.js中将stream.Readable转换为Web API ReadableStream?

将Node.js stream.Readable转换为Web API ReadableStream的简洁方案

这是《如何将Web API ReadableStream转换为Node.js stream.Readable?》的逆向问题:

  • stream.Readable是Node.js专属的流结构
  • Web API ReadableStream是WHATWG定义的Web平台通用流结构

随着Deno、Next.js Edge Runtime等非Node.js运行时的普及,将Node.js专属的ReadStream转换为通用的ReadableStream变得十分实用,比如在Next.js路由处理器中发送文件。

第一次尝试(API误用)

最初编写的代码草案如下:

const downloadStream = fs.createReadStream(zipFilePath);
const readStream = new ReadableStream({
  start(controller) {
    return pump();
    function pump() {
      return downloadStream.read().then(({ done, value }) => {
        // 没有更多数据时关闭流
        if (done) {
          controller.close();
          return;
        }
        // 将数据块加入目标流
        controller.enqueue(value);
        return pump();
      });
    }
  },
});

此方案的问题在于:Node.js的stream.Readable.read()方法不返回Promise,属于API误用。

第二次尝试(仍存在异常)

修正API调用后编写了第二版代码:

const downloadStream = fs.createReadStream(zipFilePath);
const readStream = new ReadableStream({
  start(controller) {
    return pump();
    function pump() {
      const buf = downloadStream.read() as Buffer
      if (buf === null) {
        controller.close();
        return;
      }
      controller.enqueue(buf.toString());
      return pump();
    }
  },
});

但即使文件仅344字节,调用read()立刻返回null;检查isPaused()发现流并未暂停,尝试调用pause()或指定read(1)也无法解决问题,同时收到Next.js异常:

- error Error: aborted
    at connResetException (node:internal/errors:711:14)
    at Socket.socketCloseListener (node:_http_client:454:19)
    at Socket.emit (node:events:525:35)
    at TCP.<anonymous> (node:net:313:12) {
  code: 'ECONNRESET'
}

寻求简洁解决方案

请问有没有语法更简洁的正确转换方式?


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 08:28:42