Skip to main content
流是一种重要的抽象,用于处理二进制数据而无需一次性加载到内存中。它们通常用于读取和写入文件、发送和接收网络请求,以及处理大量数据。 Bun 实现了 Web API ReadableStreamWritableStream
Bun 也实现了 node:stream 模块,包括 ReadableWritableDuplex。完整的文档请参考 Node.js 文档
要创建一个 ReadableStream
ReadableStream 的内容可以使用 for await 语法逐块读取。

Direct ReadableStream

Bun 实现了一个优化版本的 ReadableStream,避免了不必要的数据复制和队列管理。 使用传统的 ReadableStream,数据块会被_入队_。每个数据块被复制到队列中,在那里等待直到流准备好发送更多数据。
使用 direct ReadableStream,数据块会直接写入流。没有队列操作,也不需要将数据块复制到内存中。controller API 反映了这一点:你调用 .write() 而不是 .enqueue()
使用 direct ReadableStream 时,目标端处理所有数据块排队。流的消费者会精确接收到传递给 controller.write() 的内容,不进行任何编码或修改。

处理背压

controller.write() 返回写入的字节数。当目标端的内部缓冲区已满(例如,慢速的 HTTP 客户端)时,它会返回一个负数。数据块仍然被接受——负返回值是一个信号,表示暂停并等待目标端排空。 要等待排空,使用 await controller.flush(true)
对于默认(非 direct)的 ReadableStream 和异步生成器响应体,Bun 会自动应用此背压——当目标端积压时,生产方会暂停。

异步生成器流

Bun 也支持异步生成器函数作为 ResponseRequest 的数据源。使用异步生成器从异步源创建 ReadableStream
你也可以直接使用 [Symbol.asyncIterator]
要对流进行更多控制,yield 返回 direct ReadableStream controller。

Bun.ArrayBufferSink

Bun.ArrayBufferSink 类是一个快速的增量写入器,用于构建未知大小的 ArrayBuffer
要改为以 Uint8Array 形式检索数据,在 start 方法中传递 asUint8Array 选项。
.write() 方法支持字符串、类型化数组、ArrayBufferSharedArrayBuffer
一旦调用了 .end(),就不能再向 ArrayBufferSink 写入更多数据。但是,在缓冲流时,你可能希望持续写入数据并定期将内容 .flush()(例如,写入到 WritableStream)。为了支持这一点,在 start 方法中传递 stream: true
.flush() 方法以 ArrayBuffer(如果 asUint8Array: true 则为 Uint8Array)的形式返回缓冲的数据,并清除内部缓冲区。 要手动设置内部缓冲区的大小(以字节为单位),为 highWaterMark 传递一个值:

参考

查看 TypeScript 定义