ReadableStream: tee() 方法
注意:此功能在 Web Workers 中可用。
ReadableStream 接口的 tee() 方法会 复制 当前的ReadableStream,并返回一个包含两个新 ReadableStream 实例的二元素数组。
这对于允许两个读取器顺序或同时以不同速度读取流非常有用。例如,你可能在 ServiceWorker 中这样做,如果你想从服务器获取响应并将其流式传输到浏览器,同时也将其流式传输到 ServiceWorker 缓存。由于响应体不能被消耗多次,因此你需要两个副本才能做到这一点。
分叉(tee'd)的流会以两个 ReadableStream 分支中较快消费者的速率部分地回压,未读取的数据会在较慢消费的 ReadableStream 上内部排队,没有限制或回压。也就是说,当两个分支在其内部队列中都有未读元素时,原始 ReadableStream 的控制器内部队列将开始填满,一旦其 desiredSize ≤ 0 或字节流控制器 desiredSize ≤ 0,那么控制器将停止调用传递给 ReadableStream() 的底层源上的 pull(controller)。如果只有一个分支被消费,那么整个主体将被排队到内存中。因此,你不应该使用内置的 tee() 来以不同速度并行读取非常大的流。相反,请寻找一个完全回压到较慢消费分支速度的实现。
要取消流,你需要取消两个产生的分支。分叉流通常会在整个持续时间内锁定它,阻止其他读取器锁定它。
语法
tee()
参数
无。
返回值
一个包含两个 ReadableStream 实例的 Array。
异常
TypeError-
如果源流不是
ReadableStream,则抛出此错误。
示例
在下面的简单示例中,一个先前创建的流被分叉,然后生成的数组的两个成员中包含的两个流都被传递给一个函数,该函数读取两个流中的数据并将每个流的块顺序打印到 UI 的不同部分。有关完整代码,请参见 简单的分叉示例。
function teeStream() {
const teedOff = stream.tee();
fetchStream(teedOff[0], list2);
fetchStream(teedOff[1], list3);
}
function fetchStream(stream, list) {
const reader = stream.getReader();
let charsReceived = 0;
// read() returns a promise that resolves
// when a value has been received
reader.read().then(function processText({ done, value }) {
// Result objects contain two properties:
// done - true if the stream has already given you all its data.
// value - some data. Always undefined when done is true.
if (done) {
console.log("Stream complete");
return;
}
// value for fetch streams is a Uint8Array
charsReceived += value.length;
const chunk = value;
let listItem = document.createElement("li");
listItem.textContent = `Read ${charsReceived} characters so far. Current chunk = ${chunk}`;
list.appendChild(listItem);
// Read some more, and call this function again
return reader.read().then(processText);
});
}
规范
| 规范 |
|---|
| Streams # ref-for-rs-tee② |
浏览器兼容性
加载中…
另见
ReadableStream()构造函数- 分叉流