Ajax 简明教程

Stream API - Readable Streams

在 Stream API 中,可读流是我们可以顺序且异步地从中读取数据的数据源。它是从底层来源获取数据的一种标准化方式。底层来源是网络上存在的资源。它们有以下两种类型:

Push source − 在这种情况下,当你访问数据时,数据会推送到你那里。你可以控制流,比如何时开始或何时暂停,甚至何时终止当前流。例如,视频游戏流。

Pull source − 在这种情况下,你需要明确地向它们请求数据。例如,使用 Fetch 或 XHR 调用访问文件。

在可读流中,数据以小块的形式存在,因此一次一个块地顺序读取。一个块可以是一个字节,也可以是更大的大小。因此,数据块的大小在流中可以不同。现在让我们了解可读流如何工作。

Working of Readable Stream

可读流的工作非常直接。在可读流中,数据块被放置在队列中。这意味着这些块正在等待读取队列。这里我们有另一个队列,这是一个内部队列,用于跟踪未读块。这些块由读者读取。它一次处理一个块的数据,并允许你对数据执行操作。一个读者一次只能读取一个流。当读者开始读取流时,该流就被锁定,该读者表示不允许其他读者读取该流。如果你希望另一个读者读取该流,则必须终止第一个读者或可以创建一个分流流。此外,每个读者都有自己的控制器,它允许你控制流,例如开始、关闭或暂停。

它还有一个使用者,负责处理从可读流接收的数据并对其进行处理,并且能够对其进行操作。

readable stream

Readable Stream Interfaces

Stream API 支持三种类型的可读流接口:

  1. ReableStream Interface

  2. ReableStreamDefaultReader Interface

  3. ReadableStreamDefaultController Interface

ReadableStream Interface

ReadableStream 接口用于表示可读的数据流。它通常与 Fetch API 一起使用,以处理响应流。它还可以处理开发者定义的流的响应流。

Constructor

要为给定的处理程序创建一个可读流对象,ReadableStream 接口提供了一个 ReadableStream() 构造函数。

Syntax

const newRead = new ReadableStream()
Or
const newRead = new ReadableStream(UnderlyingSource)
Or
const newRead = new ReadableStream(UnderlyingSource, QueuingStrategy)

以下是 ReadableStream() 构造函数的可选参数:

UnderlyingSource − 这个对象提供了各种方法和属性,它们定义了流实例的行为。这些方法是:start()、pull() 和 cancel(),而这些属性是:type 和 autoAllocateChunkSize。

QueuingStrategy −此对象用于为给定的流定义排队策略。它采用两个参数:highWaterMark 和 size(chunk)。

Instance Properties

ReadableStream 接口提供的属性为只读属性。因此 ReadableStream 提供的属性为:

Sr.No.

Property & Description

1

ReadableStream.locked 此属性用于检查可读流是否已被锁定到某个读者。

Methods

以下为 ReadableStream 接口常用的方法:

Sr.No.

Method & Description

1

ReadableStream.cancel() 此方法返回一个 Promise,当该流已取消时该 Promise 会完成。

2

ReadableStream.getReader() 此方法用于创建一个读者并将其锁定到该流。在释放此读者之前,不允许有其他读者。

3

ReadableStream.pipeThrough() 此方法用于创建一个可链式的方式,以将当前流通过一个转换流进行传输。

4

ReadableStream.pipeTo() 此方法用于将当前 ReadableStream 传输到给定的 WriteableStream。如果传输过程成功完成,则它将返回一个 Promise;如果由于某个错误而导致传输失败,则它将对其进行拒绝。

5

ReadableStream.tee() 此方法用于获取一个包含两个结果分支的双元素数组,这两个分支作为新的 ReadableStream 对象。

ReadableStreamDefaultReader Interface

ReadableStreamDefaultReader 接口用于表示一个默认读者,此默认读者会从网络中读取流数据。它也可以从 ReadableStream 读取。

Constructor

为了创建一个 readableStreamDefualtReader 对象,ReadableStreamDefaultReader 接口提供了一个 ReadableStreamDefaultReader() 构造函数。

Syntax

const newRead = new ReadableStreamDefaultReader(myStream)

此构造函数仅包含一个参数,它便是 myStream。它将读取 ReadableStream。

Instance Properties

ReadableStreamDefaultReader 接口提供的属性为只读属性。因此 ReadableStreamDefaultReader 提供的属性为:

Sr.No.

Property & Description

1

ReadableStreamDefaultReader.closed 此属性返回一个 Promise,当该流因某个错误而关闭或被拒绝时,该 Promise 会完成。这允许你编写一个程序,该程序将在流处理过程结束时做出响应。

Methods

以下为 ReadableStream 接口常用的方法:

Sr.No.

Method & Description

1

ReadableStreamDefaultReader.cancel() 此方法返回一个 Promise,当该流已取消时该 Promise 会完成。

2

ReadableStreamDefaultReader.read() 此方法返回一个 Promise,该 Promise 将提供对流队列中的下一个区块或数据块的访问。

3

ReadableStreamDefaultReader.releaseLock() 此方法用于取消该流上读者的锁定。

ReadableStreamDefaultController Interface

ReadableStreamDefaultController 接口表示一个控制器,它允许我们控制 ReadableStream 状态或内部队列。它不提供任何控制器,并且在构造 ReadableStream 时会自动创建该实例。

Instance Properties

Sr.No.

Property & Description

1

ReadableStreamDefaultController.desiredSize 此属性用于查找填充流内部队列所需的容量大小。

ReadableStreamDefaultController 接口提供的属性为只读属性。因此 ReadableStreamDefaultController 提供的属性为:

Methods

以下是 ReadableStreamDefaultController 接口常用的方式 -

Sr.No.

Property & Description

1

ReadableStreamDefaultController.close() 此方法用于关闭相关流。

2

ReadableStreamDefaultController.enqueue() 此方法用于将指定数据块或片段放入相关流中。

3

ReadableStreamDefaultController.error() 此方法将导致任何未来的交互与相关流到错误。

Example - Creating ReadableStream

在以下程序中,我们将使用 ReadableStream 构造函数创建一个自定义可读流。因此,我们首先创建了一个以块为单位生成数据的函数。然后,我们使用包含 start() 函数的 ReadableStream() 构造函数创建一个可读流。此 start() 函数使用 pData() 递归函数,该函数通过控制器将 myData() 功能中的数据推给使用者,其中每个推送操作之间设置 1 秒的超时。现在,我们使用 getReader() 函数创建读取器以使用流中的数据。然后,我们创建一个 readMyData() 函数,以在读者的帮助下从流中递归读取数据。流结束时,完成标志设置为 true,我们退出递归循环。

<!DOCTYPE html>
<html>
<body>
<script>
   // Function that produces data for the stream
   function* myData() {
      yield 'pink';
      yield 'blue';
      yield 'yellow';
      yield 'green';
   }
   // Create a readable stream using ReadableStream() function
   const readStream = new ReadableStream({
      start(controller) {
         const data = myData();

         // Adding data to the stream
         function pData() {
            const { done, value } = data.next();

            if (done) {
               // Close the stream if no more data is available
               controller.close();
               return;
            }
            // Pushing the data to the consumer
            controller.enqueue(value);

            // Continue pushing data after 1 sec
            setTimeout(pData, 1000);
         }
         // Calling the pData function to start pushing data
         pData();
      }
   });
   // Create a reader for the readable stream
   const myreader = readStream.getReader();
   function readMyData() {
      myreader.read().then(({ done, value }) => {
         if (done) {
            // Stream is closed
            console.log('Stream is closed');
            return;
         }
         // Processing the received data
         console.log('Received data:', value);

         // Continue reading the data
         readMyData();
      });
   }
   // Calling readMyData() function to start
   // reading data from the readable stream
   readMyData();
</script>
</body>
</html>

Output

readable stream2

Conclusion

因此,这是流 API 中的可读流。它们是流 API 中最重要的且最常用的流。它们几乎受所有网络浏览器支持,例如 Chrome、Firefox、opera、edge、safari 等。现在在下一篇文章中,我们将学习有关流 API 的可写流。