流 API - 可讀流



在 Stream API 中,可讀流是一個數據源,我們可以從中以順序和非同步的方式讀取資料。它是一種標準化的從底層源獲取資料的方式。底層源是網路上存在的資源。它們有以下兩種型別:

推送源 - 當您訪問資料時,資料會被推送給您。您可以控制流,例如何時啟動、何時暫停甚至何時終止當前流。例如,影片遊戲流。

拉取源 - 您需要顯式地向它們請求資料。例如,使用 Fetch 或 XHR 呼叫訪問檔案。

在可讀流中,資料以小塊的形式存在,因此它被順序讀取,一次讀取一塊。一塊可以是一個位元組,也可以是更大的大小。因此,流中塊的大小可能不同。現在讓我們瞭解可讀流是如何工作的。

可讀流的工作原理

可讀流的工作原理非常簡單。在可讀流中,資料塊被放置在佇列中。這意味著塊正在佇列中等待讀取。這裡我們還有一個內部佇列,它跟蹤未讀取的塊。塊由讀取器讀取。它一次處理一個塊的資料,並允許您對資料執行操作。一個讀取器一次只能讀取一個流。當讀取器開始讀取流時,該流對該讀取器被鎖定,這意味著不允許其他讀取器讀取該流。如果您想讓另一個讀取器讀取該流,則必須終止第一個讀取器或建立一個 tee 流。此外,每個讀取器都有自己的控制器,允許您控制流,例如啟動、關閉或暫停。

它還有一個使用者,負責處理從可讀流接收到的資料並對其進行處理,並能夠對其執行操作。

Readable Stream

可讀流介面

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() 建構函式的可選引數:

UnderlyingSource - 此物件提供各種方法和屬性,這些方法和屬性定義了流例項的行為。方法包括:start()、pull() 和 cancel(),而屬性包括:type 和 autoAllocateChunkSize。

QueuingStrategy - 此物件用於為給定的流定義排隊策略。它採用兩個引數:highWaterMark 和 size(chunk)。

例項屬性

ReadableStream 介面提供的屬性是隻讀屬性。因此,ReadableStream 提供的屬性是:

序號 屬性和描述
1

ReadableStream.locked

此屬性用於檢查可讀流是否被鎖定到讀取器。

方法

以下是 ReadableStream 介面常用的方法:

序號 方法和描述
1

ReadableStream.cancel()

此方法返回一個 promise,當流被取消時,該 promise 將被 resolve。

2

ReadableStream.getReader()

此方法用於建立讀取器並將其鎖定到流。在釋放此讀取器之前,不允許其他讀取器使用。

3

ReadableStream.pipeThrough()

此方法用於建立一種可連結的方式,將當前流透過變換流進行管道傳輸。

4

ReadableStream.pipeTo()

此方法用於將當前 ReadableStream 管道傳輸到給定的 WriteableStream。當管道傳輸過程成功完成或由於某些錯誤而被拒絕時,它將返回一個 promise。

5

ReadableStream.tee()

此方法用於獲取一個包含兩個結果分支作為新的 ReadableStream 物件的二元素陣列。

ReadableStreamDefaultReader 介面

ReadableStreamDefaultReader 介面用於表示預設讀取器,該讀取器將從網路讀取流資料。它也可以從 ReadableStream 讀取。

建構函式

要建立 readableStreamDefualtReader 物件,ReadableStreamDefaultReader 介面提供了一個 ReadableStreamDefaultReader() 建構函式。

語法

const newRead = new ReadableStreamDefaultReader(myStream)

此建構函式只包含一個引數 myStream。它將讀取 ReadableStream。

例項屬性

ReadableStreamDefaultReader 介面提供的屬性是隻讀屬性。因此,ReadableStreamDefaultReader 提供的屬性是:

序號 屬性和描述
1

ReadableStreamDefaultReader.closed

此屬性返回一個 promise,當流關閉或由於某些錯誤而被拒絕時,該 promise 將被 resolve。它允許您編寫一個程式,該程式將在流處理結束時做出響應。

方法

以下是 ReadableStream 介面常用的方法:

序號 方法和描述
1

ReadableStreamDefaultReader.cancel()

此方法返回一個 promise,當流被取消時,該 promise 將被 resolve。

2

ReadableStreamDefaultReader.read()

此方法返回一個 promise,該 promise 將訪問流佇列中的下一個塊或片段。

3

ReadableStreamDefaultReader.releaseLock()

此方法用於移除讀取器對流的鎖定。

ReadableStreamDefaultController 介面

ReadableStreamDefaultController 介面表示一個控制器,它允許我們控制 ReadableStream 狀態或內部佇列。它不提供任何控制器,例項在構造 ReadableStream 時自動建立。

例項屬性

序號 屬性和描述
1

ReadableStreamDefaultController.desiredSize

此屬性用於查詢要填充流的內部佇列的所需大小。

ReadableStreamDefaultController 介面提供的屬性是隻讀屬性。因此,ReadableStreamDefaultController 提供的屬性是:

方法

以下是 ReadableStreamDefaultController 介面常用的方法:

序號 屬性和描述
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 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>

輸出

Readable Stream

結論

這就是 Stream API 中的可讀流。它們是 Stream API 中最重要和最常用的流。幾乎所有 Web 瀏覽器(如 Chrome、Firefox、Opera、Edge、Safari 等)都支援它們。在下一篇文章中,我們將學習 Stream API 的可寫流。

廣告