ReadableStream
注意:此功能在Web Workers中可用。
ReadableStream
接口是流 API的一部分,表示一个可读的字节数据流。Fetch API通过body
属性提供了一个具体的 ReadableStream
实例Response
对象。
ReadableStream
是一个可传输对象。
构造函数
ReadableStream()
-
根据给定的处理程序创建并返回一个可读流对象。
实例属性
ReadableStream.locked
只读-
返回一个布尔值,指示可读流是否锁定到某个读取器。
静态方法
ReadableStream.from()
实验性-
从提供的可迭代或异步可迭代对象(例如数组、集合、异步生成器等)返回
ReadableStream
。
实例方法
ReadableStream.cancel()
-
返回一个
Promise
,该 Promise 在流被取消时解析。调用此方法表示消费者不再对流感兴趣。提供的reason
参数将传递给底层源,底层源可能会使用它也可能不会使用它。 ReadableStream.getReader()
-
创建一个读取器并将流锁定到它。在流被锁定期间,无法获取其他读取器,直到当前读取器被释放。
ReadableStream.pipeThrough()
-
提供了一种可链接的方式,用于将当前流通过转换流或任何其他可写/可读对进行管道传输。
ReadableStream.pipeTo()
-
将当前 ReadableStream 管道传输到给定的
WritableStream
并返回一个Promise
,该 Promise 在管道传输过程成功完成时完成,或者在遇到任何错误时拒绝。 ReadableStream.tee()
-
tee
方法分流此可读流,返回一个包含两个结果分支作为新ReadableStream
实例的双元素数组。这两个流中的每一个都接收相同的数据。
异步迭代
ReadableStream
实现异步可迭代协议。这使得可以使用for await...of
语法异步迭代流中的块。
const stream = new ReadableStream(getSomeSource());
for await (const chunk of stream) {
// Do something with each 'chunk'
}
异步迭代器消耗流,直到流用尽数据或以其他方式终止。循环也可以由于 break
、throw
或 return
语句提前退出。
在迭代过程中,流被锁定以防止其他消费者获取读取器(尝试迭代已经锁定的流将抛出 TypeError
)。当循环退出时,此锁将被释放。
默认情况下,退出循环也将取消流,以便它不能再被使用。要在退出循环后继续使用流,请将 { preventCancel: true }
传递到流的 values()
方法。
for await (const chunk of stream.values({ preventCancel: true })) {
// Do something with 'chunk'
break;
}
// Acquire a reader for the stream and continue reading ...
示例
获取流
在以下示例中,创建了一个人工Response
,用于将从另一个资源获取的 HTML 片段流式传输到浏览器。
它演示了 ReadableStream
与Uint8Array
结合使用的用法。
fetch("https://www.example.org")
.then((response) => response.body)
.then((rb) => {
const reader = rb.getReader();
return new ReadableStream({
start(controller) {
// The following function handles each data chunk
function push() {
// "done" is a Boolean and value a "Uint8Array"
reader.read().then(({ done, value }) => {
// If there is no more data to read
if (done) {
console.log("done", done);
controller.close();
return;
}
// Get the data and send it to the browser via the controller
controller.enqueue(value);
// Check chunks by logging to the console
console.log(done, value);
push();
});
}
push();
},
});
})
.then((stream) =>
// Respond with our stream
new Response(stream, { headers: { "Content-Type": "text/html" } }).text(),
)
.then((result) => {
// Do things with result
console.log(result);
});
将迭代器或异步迭代器转换为流
from()
静态方法可以将迭代器(例如Array
或Map
)或(异步)迭代器转换为可读流。
const myReadableStream = ReadableStream.from(iteratorOrAsyncIterator);
在不支持 from()
方法的浏览器上,您可以创建自己的自定义可读流来实现相同的结果。
function iteratorToStream(iterator) {
return new ReadableStream({
async pull(controller) {
const { value, done } = await iterator.next();
if (value) {
controller.enqueue(value);
}
if (done) {
controller.close();
}
},
});
}
警告:此示例假设返回值(当 done
为 true
时为 value
),如果存在,也是要入队的块。某些迭代器 API 可能将返回值用于不同的目的。您可能需要根据您正在交互的 API 调整代码。
使用 for await...of 对流进行异步迭代
此示例显示了如何使用for await...of
循环迭代到达的块来处理 fetch()
响应。
const response = await fetch("https://www.example.org");
let total = 0;
// Iterate response.body (a ReadableStream) asynchronously
for await (const chunk of response.body) {
// Do something with each chunk
// Here we just accumulate the size of the response.
total += chunk.length;
}
// Do something with the total
console.log(total);
规范
规范 |
---|
流标准 # rs-class |
浏览器兼容性
BCD 表格仅在启用 JavaScript 的浏览器中加载。
另请参阅
- 流 API 概念
- 使用可读流
- 使用可读字节流
- WHATWG 流可视化工具,用于可读、可写和转换流的基本可视化。
- web-streams-polyfill 或 sd-streams - polyfills