ReadableStream 和 WritableStream。
Bun 也实现了
node:stream 模块,包含 Readable、
Writable 和
Duplex。 更多完整文档请参考 Node.js
文档。ReadableStream:
for await 语法逐块读取 ReadableStream 的内容。
直接 ReadableStream
Bun 实现了一个经过优化的 ReadableStream,避免了不必要的数据复制和队列管理。
在传统的 ReadableStream 中,数据块是被 入队 的。每个数据块都会被复制到一个队列中,直到流准备好发送更多数据时才会被读取。
ReadableStream 时,数据块会直接写入流中。不会发生排队,也不需要将数据块复制到内存中。controller API 也反映了这一点:调用 .write() 而不是 .enqueue()。
ReadableStream 时,目标端会处理所有的数据块队列。流的消费者将收到与传给 controller.write() 完全一致的内容,不进行任何编码或修改。
处理背压
controller.write() 返回已写入的字节数;当目标端的内部缓冲区已满时(例如,一个速度较慢的 HTTP 客户端),则返回一个待处理的 Promise<number>。无论哪种情况,数据块都会被接受;该 Promise 会在目标端完成排空后解析,因此只需对结果使用 await 即可:
await controller.flush(true) 与此等效,可以在写入返回 Promise 后使用。
对于默认的(非 direct)ReadableStream 和异步生成器响应体,Bun 会自动应用这种背压机制——当目标端出现积压时,生产者会暂停。
异步生成器流
Bun 也支持将异步生成器函数作为Response 和 Request 的数据源。使用异步生成器创建一个从异步源获取数据的 ReadableStream。
[Symbol.asyncIterator]。
yield 会返回直接的 ReadableStream 控制器。
Bun.ArrayBufferSink
Bun.ArrayBufferSink 类是一个用于构造未知大小 ArrayBuffer 的高速增量写入器。
Uint8Array 格式获取数据,可以向 start 方法传入 asUint8Array 选项。
.write() 方法支持字符串、类型化数组、ArrayBuffer 和 SharedArrayBuffer。
.end() 后,无法再向 ArrayBufferSink 写入数据。但是,在缓冲流时,你可能希望继续写入数据,并定期调用 .flush() 刷新内容(例如写入 WritableStream)。要实现此功能,请向 start 方法传入 stream: true。
.flush() 方法会将缓冲的数据作为 ArrayBuffer 返回(如果设置了 asUint8Array: true,则返回 Uint8Array),并清空内部缓冲区。
如果需要手动设置内部缓冲区的大小(以字节为单位),请传入 highWaterMark:
参考
查看可展开的 TypeScript 定义