Stream API - 可读流
在 Stream API 中,可读流是一个数据源,我们可以从其中以顺序和异步方式读取数据。 它是从底层源获取数据的标准化方法。 底层资源是网络上存在的资源。 它们有以下两种类型−
Push 源 − 当您访问数据时,数据会推送给您。 您可以控制流,例如何时开始或何时暂停,甚至何时终止当前流。 例如,视频游戏流媒体。
Pull 源 − 您需要明确地向他们请求数据。 例如,借助 Fetch 或 XHR 调用访问文件。
在可读流中,数据采用小块的形式,因此可以按顺序读取,一次读取一个块。 块可以是单个字节,也可以是更大的大小。 因此,流中块的大小可以不同。 现在让我们了解可读流是如何工作的。
可读流的工作
可读流的工作非常简单。 在可读流中,数据块被放入队列中。 这意味着块正在队列中等待读取。 这里我们有另一个队列,它是一个内部队列,用于跟踪未读的块。 这些块由读取器读取。 它一次处理一个块的数据,并允许您对数据执行操作。 一个读取器一次只能读取一个流。 当读取器开始读取流时,该读取器将锁定该流,这意味着不允许其他读取器读取该流。 如果您希望另一个读取器读取该流,则必须终止第一个读取器或者可以创建一个 tee 流。 此外,每个读取器都有自己的控制器,允许您控制流,例如启动、关闭或暂停。
它还有一个消费者,负责处理从可读流接收到的数据并对其进行处理,并能够对其执行操作。
可读流接口
Stream API支持三种类型的可读流接口 −
ReableStream接口
ReableStreamDefaultReader 接口
ReadableStreamDefaultController 接口
ReadableStream 接口
ReadableStream 接口用于表示可读的数据流。 它通常与 Fetch API 一起使用来处理响应流。 它还可以处理开发人员定义的流的响应流。
构造函数
为给定处理程序创建可读流对象 ReadableStream 接口提供了 ReadableStream() 构造函数。
语法
const newRead = new ReadableStream() Or const newRead = new ReadableStream(UnderlyingSource) Or const newRead = new ReadableStream(UnderlyingSource, QueuingStrategy)
以下是 ReadableStream() 构造函数的可选参数 −
底层源 − 该对象提供定义流实例行为的各种方法和属性。 方法是:start()、pull() 和 cancel(),而属性是:type 和 autoAllocateChunkSize。
排队策略 − 该对象用于定义给定流的排队策略。 它需要两个参数:highWaterMark 和 size(chunk)。
实例属性
ReadableStream 接口提供的属性是只读属性。 所以ReadableStream提供的属性是 −
Sr.No. | 属性和描述 |
---|---|
1 | ReadableStream.locked 该属性用于检查可读流是否被锁定到读取器。 |
方法
以下是ReadableStream接口的常用方法 −
Sr.No. | 方法及说明 |
---|---|
1 | ReadableStream.cancel() 此方法返回一个promise ,该promise 将在流取消时解析。 |
2 | ReadableStream.getReader() 此方法用于创建读取器并将流锁定到它。 在该读取器被释放之前,不允许其他读取器。 |
3 | ReadableStream.pipeThrough() 此方法用于创建通过转换流传输当前流的可链接方式。 |
4 | ReadableStream.pipeTo() 此方法用于将当前的 ReadableStream 传输到给定的 WriteableStream。 当管道过程成功完成或由于某些错误而拒绝时,它将返回一个promise 。 |
5 | ReadableStream.tee() 此方法用于获取一个二元素数组,其中包含两个结果分支作为新的 ReadableStream 对象。 |
ReadableStreamDefaultReader 接口
ReadableStreamDefaultReader 接口用于表示将从网络读取流数据的默认读取器。 也可以从 ReadableStream 中读取。
构造函数
为了创建一个 ReadableStreamDefaultReader 对象,ReadableStreamDefaultReader 接口提供了一个 ReadableStreamDefaultReader() 构造函数。
语法
const newRead = new ReadableStreamDefaultReader(myStream)
该构造函数仅包含一个参数,即 myStream。 它将读取 ReadableStream。
实例属性
ReadableStreamDefaultReader 接口提供的属性是只读属性。 所以 ReadableStreamDefaultReader 提供的属性是 −
Sr.No. | 属性和描述 |
---|---|
1 | ReadableStreamDefaultReader.closed 此属性返回一个 promise,当流因某些错误而关闭或拒绝时,该promise 将得到解决。 它允许您编写一个程序,该程序将在流处理结束时做出响应。 |
方法
以下是ReadableStream接口的常用方法 −
Sr.No. | 方法及说明 |
---|---|
1 | ReadableStreamDefaultReader.cancel() 此方法返回一个promise ,该promise 将在流取消时解析。 |
2 | ReadableStreamDefaultReader.read() 此方法返回一个promise ,该promise 将允许访问流队列中的下一个块或片段。 |
3 | ReadableStreamDefaultReader.releaseLock() 该方法用于解除读取器对流的锁定。 |
ReadableStreamDefaultController 接口
ReadableStreamDefaultController 接口代表一个控制器,它允许我们控制 ReadableStream 状态或内部队列。 它不提供任何控制器,实例是在构造 ReadableStream 时自动创建的。
实例属性
Sr.No. | 属性和描述 |
---|---|
1 | ReadableStreamDefaultController.desiredSize 此属性用于查找填充流内部队列所需的大小。 |
ReadableStreamDefaultController 接口提供的属性是只读属性。 所以ReadableStreamDefaultController提供的属性是 −
方法
以下是ReadableStreamDefaultController接口的常用方法 −
Sr.No. | 属性和描述 |
---|---|
1 | ReadableStreamDefaultController.close() 该方法用于关闭相关流。 |
2 | ReadableStreamDefaultController.enqueue() 此方法用于将指定的块或片放入相关流中。 |
3 | ReadableStreamDefaultController.error() 此方法将导致未来与相关流的任何交互出现错误。 |
示例 - 创建 ReadableStream
在下面的程序中,我们将使用 ReadableStream 构造函数创建一个自定义可读流。 因此,首先我们创建一个生成块数据的函数。 然后我们使用包含 start() 函数的 ReadableStream() 构造函数创建一个可读流。 此 start() 函数使用 pData() 递归函数,在控制器的帮助下将数据从 myData() 函数推送到使用者,其中每次推送操作之间的超时设置为 1 秒。 现在我们创建一个读取器来使用 getReader() 函数使用流中的数据。 然后我们创建一个 readMyData() 函数,在阅读器的帮助下递归地从流中读取数据。 当流结束时,done 标志被设置为 true,并且我们退出递归循环。
<!DOCTYPE html> <html> <body> <script> // 为流生成数据的函数 function* myData() { yield 'pink'; yield 'blue'; yield 'yellow'; yield 'green'; } // 使用 ReadableStream() 函数创建可读流 const readStream = new ReadableStream({ start(controller) { const data = myData(); // 将数据添加到流中 function pData() { const { done, value } = data.next(); if (done) { // 如果没有更多数据可用,则关闭流 controller.close(); return; } // 将数据推送给消费者 controller.enqueue(value); // 1秒后继续推送数据 setTimeout(pData, 1000); } // 调用pData函数开始推送数据 pData(); } }); // 为可读流创建一个读取器 const myreader = readStream.getReader(); function readMyData() { myreader.read().then(({ done, value }) => { if (done) { // Stream is closed console.log('Stream is closed'); return; } // 处理接收到的数据 console.log('Received data:', value); // 继续读取数据 readMyData(); }); } // 调用readMyData()函数开始 // 从可读流中读取数据 readMyData(); </script> </body> </html>
输出
结论
这就是 Stream API 中的可读流。 它们是 Stream API 中最重要和最常用的流。 几乎所有的网络浏览器都支持它们,如 Chrome、Firefox、opera、edge、safari 等。在下一篇文章中,我们将了解 Stream API 的可写流。