blob: 2fa7ce6e0fea19f1552e7e8b9a62af4350b1d1d5 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
---
title: Streams API
slug: Web/API/Streams_API
translation_of: Web/API/Streams_API
---
<div>{{SeeCompatTable}}{{APIRef("Streams")}}</div>
<p class="summary">Streams API允许JavaScript以编程的方式访问通过网络接收的数据流,并根据开发人员的需要处理它们。</p>
<h2 id="概念和用法">概念和用法</h2>
<p>流将你希望通过网络接收的资源拆分成小块,然后按位处理它。这正是浏览器在接收用于显示web页面的资源时做的事情——视频缓冲区和更多的内容可以逐渐播放,有时候随着内容的加载,你可以看到图像逐渐地显示。</p>
<p>但曾经这些对于JavaScript是不可用的。以前,如果我们想要处理某种资源(如视频、文本文件等),我们必须下载完整的文件,等待它反序列化成适当的格式,然后在完整地接收到所有的内容后再进行处理。</p>
<p>随着流在JavaScript中的使用,一切发生了改变——只要原始数据在客户端可用,你就可以使用JavaScript 按位处理它,而不再需要缓冲区、字符串或blob。</p>
<p><img alt="" src="https://mdn.mozillademos.org/files/15817/Concept.png" style="display: block; height: 382px; margin: 0px auto; width: 1000px;"></p>
<p>还有更多的优点——你可以检测流何时开始或结束,将流链接在一起,根据需要处理错误和取消流,并对流的读取速度做出反应。</p>
<p>流的基础应用围绕着使响应可以被流处理展开。例如,一个成功的 <a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch">fetch request</a> 响应 {{domxref("Body")}} 会暴露为 {{domxref("ReadableStream")}},之后你就可以使用 {{domxref("ReadableStream.getReader()")}} 建立的 reader 读取它,使用 {{domxref("ReadableStream.cancel()")}} 取消它等等。</p>
<p>更复杂的应用包括使用 {{domxref("ReadableStream.ReadableStream", "ReadableStream()")}} 创建你自己的流,比如在 <a href="/en-US/docs/Web/API/Service_Worker_API">service worker</a> 中处理数据。</p>
<p>你还可以使用 {{domxref("WritableStream")}} 将数据写入流中。</p>
<div class="note">
<p><strong>注意:</strong>你可以在这些文章中找到关于流理论的更多细节和实践 — <a href="/en-US/docs/Web/API/Streams_API/Concepts">Streams API concepts</a>, <a href="/en-US/docs/Web/API/Streams_API/Using_readable_streams">Using readable streams</a>,以及 <a href="/en-US/docs/Web/API/Streams_API/Using_writable_streams">Using writable streams</a>。</p>
</div>
<h2 id="Stream_接口">Stream 接口</h2>
<h3 id="Readable_streams">Readable streams</h3>
<dl>
<dt>{{domxref("ReadableStream")}}</dt>
<dd>表示数据的可读流。用于处理 <a href="/en-US/docs/Web/API/Fetch_API">Fetch API</a> 返回的响应,或者开发者自定义的流(例如通过 {{domxref("ReadableStream.ReadableStream", "ReadableStream()")}} 构造的流)。</dd>
<dt>{{domxref("ReadableStreamDefaultReader")}}</dt>
<dd>表示默认阅读器,用于阅读来自网络的数据流(例如 fetch 请求)。</dd>
<dt>{{domxref("ReadableStreamDefaultController")}}</dt>
<dd>表示控制器,用于控制 {{domxref("ReadableStream")}} 的状态及内部队列。默认的控制器用于处理非字节流。</dd>
</dl>
<h3 id="Writable_streams">Writable streams</h3>
<dl>
<dt>{{domxref("WritableStream")}}</dt>
<dd>提供了将流写入目标这个过程的标准抽象表示,称为 sink。内置了背压和队列机制。</dd>
<dt>{{domxref("WritableStreamDefaultWriter")}}</dt>
<dd>表示默认写入器,用于将小块的数据写入可写流中。</dd>
<dt>{{domxref("WritableStreamDefaultController")}}</dt>
<dd>表示控制器,用于控制 {{domxref("WritableStream")}} 的状态。当创建一个 <code>WritableStream</code> 时,对应的 <code>WritableStreamDefaultController</code> 实例会被提供给底层的 sink 供其操作。</dd>
</dl>
<h3 id="流相关的_API_及操作">流相关的 API 及操作</h3>
<dl>
<dt>{{domxref("ByteLengthQueuingStrategy")}}</dt>
<dd>提供建立流时所需的内置字节队列策略。</dd>
<dt>{{domxref("CountQueuingStrategy")}}</dt>
<dd>提供建立流时所需的块计数队列策略。</dd>
</dl>
<h3 id="扩展">扩展</h3>
<dl>
<dt>{{domxref("Request")}}</dt>
<dd>当构造一个新的 <code>Request</code> 对象后,你可以给它的 <code>RequestInit</code> 中的 <code>body</code> 属性传入一个 {{domxref("ReadableStream")}}。这个 <code>Request</code> 对象就可以被传入 {{domxref("WindowOrWorkerGlobalScope.fetch()")}} 中,开始接收流。</dd>
<dt>{{domxref("Body")}}</dt>
<dd>一个成功的 <a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch">fetch request</a> 响应 {{domxref("Body")}} 会默认暴露为 {{domxref("ReadableStream")}},从而可以采用相应的阅读器来处理等。</dd>
</dl>
<h3 id="字节流相关接口">字节流相关接口</h3>
<div class="warning">
<p><strong>重要:</strong>下面的 API 并没有在所有浏览器中都实现,关于规范细节是否处于完成状态可供实现还存在疑问。它们可能随时会改变。</p>
</div>
<dl>
<dt>{{domxref("ReadableStreamBYOBReader")}}</dt>
<dd>表示 BYOB("bring your own buffer")阅读器,用于阅读开发者提供的流数据(如自定义的 {{domxref("ReadableStream.ReadableStream", "ReadableStream()")}})。</dd>
<dt>{{domxref("ReadableByteStreamController")}}</dt>
<dd>表示控制器,用于控制 {{domxref("ReadableStream")}} 的状态及内部队列。字节控制器用于处理字节流。</dd>
<dt>{{domxref("ReadableStreamBYOBRequest")}}</dt>
<dd>表示 {{domxref("ReadableByteStreamController")}} 中的 BYOB pull request。</dd>
</dl>
<h2 id="Examples">Examples</h2>
<p>We have created a directory of examples to go along with the Streams API documentation — see <a href="https://github.com/mdn/dom-examples/tree/master/streams">mdn/dom-examples/streams</a>. The examples are as follows:</p>
<ul>
<li><a href="http://mdn.github.io/dom-examples/streams/simple-pump/">Simple stream pump</a>: This example shows how to consume a ReadableStream and pass its data to another.</li>
<li><a href="http://mdn.github.io/dom-examples/streams/grayscale-png/">Grayscale a PNG</a>: This example shows how a ReadableStream of a PNG can be turned into grayscale.</li>
<li><a href="http://mdn.github.io/dom-examples/streams/simple-random-stream/">Simple random stream</a>: This example shows how to use a custom stream to generate random strings, enqueue them as chunks, and then read them back out again.</li>
<li><a href="http://mdn.github.io/dom-examples/streams/simple-tee-example/">Simple tee example</a>: This example extends the Simple random stream example, showing how a stream can be teed and both resulting streams can be read independently.</li>
<li><a href="http://mdn.github.io/dom-examples/streams/simple-writer/">Simple writer</a>: This example shows how to to write to a writable stream, then decode the stream and write the contents to the UI.</li>
<li><a href="http://mdn.github.io/dom-examples/streams/png-transform-stream/">Unpack chunks of a PNG</a>: This example shows how <a href="https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/pipeThrough"><code>pipeThrough()</code></a> can be used to transform a ReadableStream into a stream of other data types by transforming a data of a PNG file into a stream of PNG chunks.</li>
</ul>
<p>Examples from other developers:</p>
<ul>
<li><a href="https://fetch-progress.anthum.com/">Progress Indicators with Streams, Service Workers, & Fetch</a>.</li>
</ul>
<h2 id="Specifications">Specifications</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">Specification</th>
<th scope="col">Status</th>
<th scope="col">Comment</th>
</tr>
<tr>
<td>{{SpecName('Streams')}}</td>
<td>{{Spec2('Streams')}}</td>
<td>Initial definition.</td>
</tr>
</tbody>
</table>
<h2 id="Browser_compatibility">Browser compatibility</h2>
<div class="hidden">
<p>The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p>
</div>
<h3 id="ReadableStream">ReadableStream</h3>
<p>{{Compat("api.ReadableStream")}}</p>
<h3 id="WritableStream">WritableStream</h3>
<p>{{Compat("api.WritableStream")}}</p>
<h2 id="See_also">See also</h2>
<ul>
<li><a href="/en-US/docs/Web/API/Streams_API/Concepts">Streams API concepts</a></li>
<li><a href="/en-US/docs/Web/API/Streams_API/Using_readable_streams">Using readable streams</a></li>
<li><a href="/en-US/docs/Web/API/Streams_API/Using_writable_streams">Using writable streams</a></li>
</ul>
|