如何在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
相关产品推荐
相关产品推荐

