Skip to main content
流是处理二进制数据而无需一次性全部加载到内存中的重要抽象。它们通常用于读写文件、发送和接收网络请求以及处理大量数据。 Bun 实现了 Web API 中的 ReadableStreamWritableStream
Bun 也实现了 node:stream 模块,包含 ReadableWritableDuplex。 更多完整文档请参考 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 后使用。 对于默认的(非 directReadableStream 和异步生成器响应体,Bun 会自动应用这种背压机制——当目标端出现积压时,生产者会暂停。

异步生成器流

Bun 也支持将异步生成器函数作为 ResponseRequest 的数据源。使用异步生成器创建一个从异步源获取数据的 ReadableStream
你也可以直接使用 [Symbol.asyncIterator]
如需更精细地控制流,yield 会返回直接的 ReadableStream 控制器。

Bun.ArrayBufferSink

Bun.ArrayBufferSink 类是一个用于构造未知大小 ArrayBuffer 的高速增量写入器。
如果需要以 Uint8Array 格式获取数据,可以向 start 方法传入 asUint8Array 选项。
.write() 方法支持字符串、类型化数组、ArrayBufferSharedArrayBuffer
调用 .end() 后,无法再向 ArrayBufferSink 写入数据。但是,在缓冲流时,你可能希望继续写入数据,并定期调用 .flush() 刷新内容(例如写入 WritableStream)。要实现此功能,请向 start 方法传入 stream: true
.flush() 方法会将缓冲的数据作为 ArrayBuffer 返回(如果设置了 asUint8Array: true,则返回 Uint8Array),并清空内部缓冲区。 如果需要手动设置内部缓冲区的大小(以字节为单位),请传入 highWaterMark

参考

查看可展开的 TypeScript 定义