Stream API

Streams API 允许 JavaScript 以编程方式访问从网络接收的数据流,并且允许开发人员根据需要处理它们。

备注: 此特性在 Web Worker 中可用

概念和用法

流会将你想要从网络接受的资源分成一个个小的分块,然后按位处理它。这正是浏览器在接收用于显示 web 页面的资源时做的事情——视频缓冲区和更多的内容可以逐渐播放,有时候随着内容的加载,你可以看到图像逐渐地显示。

但曾经这些对于 JavaScript 是不可用的。以前,如果我们想要处理某种资源(如视频、文本文件等),我们必须下载完整的文件,等待它反序列化成适当的格式,然后在完整地接收到所有的内容后再进行处理。

随着流在 JavaScript 中的使用,一切发生了改变——只要原始数据在客户端可用,你就可以使用 JavaScript 按位处理它,而不再需要缓冲区、字符串或 blob。

还有更多的优点——你可以检测流何时开始或结束,将流链接在一起,根据需要处理错误和取消流,并对流的读取速度做出反应。

流的基础应用围绕着使响应可以被流处理展开。例如,一个成功的 fetch 请求返回的响应体可以暴露为 ReadableStream,之后你可以使用 ReadableStream.getReader() 创建一个 reader 读取它,使用 ReadableStream.cancel() 取消它等等。

更复杂的应用包括使用 ReadableStream() 构造函数创建你自己的流,例如进入 service worker 去处理流。

你也可以使用 WritableStream 将数据写入流。

备注: 你可以在这些文章中找到关于流理论的更多细节和实践——Stream API 概念使用可读流使用可读字节流 (en-US),以及使用可写流 (en-US)

Stream 接口

可读流

ReadableStream

表示数据的可读流。用于处理 Fetch API 返回的响应,或者开发者自定义的流(例如通过 ReadableStream() 构造的流)。

ReadableStreamDefaultReader

表示默认 reader,用于读取来自网络的数据流(例如 fetch 请求)。

ReadableStreamDefaultController

表示一个 controller,用于控制 ReadableStream 的状态及内部队列。默认的 controller 用于处理非字节流。

可写流

WritableStream

提供了将流写入目标这个过程的标准抽象表示,称为 sink。内置了背压和队列机制。

WritableStreamDefaultWriter

表示默认 writer,用于将分块的数据写入可写流中。

WritableStreamDefaultController

表示一个 controller,用于控制 WritableStream 的状态。当创建一个 WritableStream 时,对应的 WritableStreamDefaultController 实例会被提供给底层的 sink 供其操作。

转换流

TransformStream

表示一组可转化的数据。

TransformStreamDefaultController

提供操作和转换流关联的 ReadableStreamWritableStream 的方法。

流相关的 API 和操作

ByteLengthQueuingStrategy

当构建流时,提供建立流时所需的内置字节队列策略。

CountQueuingStrategy

当构建流时,提供建立流时所需的块计数队列策略。

其它 API 扩展

Request

当构造一个新的 Request 对象后,你可以给它的 RequestInit 中的 body 属性传入一个 ReadableStream。这个 Request 对象就可以被传入 fetch() 中,开始接收流。

Response.body

一个成功的 fetch request 响应体会默认暴露为 ReadableStream,从而可以采用相应的 reader 来处理等。

字节流相关的接口

ReadableStreamBYOBReader (en-US)

表示一个 BYOB(“带你自己的缓冲区”)reader,它可以用于读取由开发人员提供的流数据(例如一个自定义的 ReadableStream())。

ReadableByteStreamController (en-US)

表示一个 controller,用于控制 ReadableStream 的状态及内部队列。字节流 controller 用于处理字节流。

ReadableStreamBYOBRequest (en-US)

表示 ReadableByteStreamController (en-US) 中的 BYOB pull request。

示例

我们创建了流的示例目录,以配合 Streams API 文档——参见 mdn/dom-examples/streams。示例如下:

  • 简单的流 pump:此示例展示了如何消费流并且传递它的数据进入另一个。
  • 转换一个 PNG 到灰度:这个示例展示了如何使用可读流将 PNG 转换到灰度。
  • 简单随机流:这个示例展示了如何使用一个自定义流去生成随机字符串,并将将它们排入分块,然后重新读取它们。
  • 简单 tee 示例:这个示例由简单随机流扩展,展示了一个流如何被拷贝为两个并且生成的流可以被独立的读取。
  • 简单 writer:这个示例展示了如何写入可写流,然后解码流并将流内容写入 UI。
  • 解压 PNG 分块:此示例展示了如何使用 pipeThrough() 通过将 PNG 文件的数据转换为 PNG 分块流来将 ReadableStream 转换为其他数据类型的流。

来自其它开发人员的示例:

规范

Specification
Streams Standard
# rs-class
Streams Standard
# ws-class

浏览器兼容性

api.ReadableStream

BCD tables only load in the browser

api.WritableStream

BCD tables only load in the browser

参见