ReadableStreamDefaultReader: read() 方法

Baseline 已廣泛支援

此特性已相當成熟,可在許多裝置和瀏覽器版本上使用。自 ⁨2020 年 1 月⁩ 起,所有主流瀏覽器均已支援。

注意:此功能在 Web Workers 中可用。

ReadableStreamDefaultReader 介面的 read() 方法返回一個 Promise,該 Promise 提供對流內部佇列中下一個資料塊的訪問。

語法

js
read()

引數

無。

返回值

一個 Promise,它會根據流的狀態來 fulfilled/rejected。各種可能性如下:

  • 如果資料塊可用,Promise 將會 fulfilled,並帶有 `{ value: theChunk, done: false }` 形式的物件。
  • 如果流關閉,Promise 將會 fulfilled,並帶有 `{ value: undefined, done: true }` 形式的物件。
  • 如果流發生錯誤,Promise 將會 rejected,並帶有相關的錯誤。

異常

TypeError

源物件不是 ReadableStreamDefaultReader,流沒有擁有者,或者呼叫了 ReadableStreamDefaultReader.releaseLock()(當有待處理的 read 請求時)。

示例

示例 1 - 簡單示例

此示例展示了基本的 API 用法,但並未嘗試處理例如流資料塊不以換行符結束等複雜情況。

在此示例中,stream 是一個先前建立的自定義 ReadableStream。它使用透過 getReader() 建立的 ReadableStreamDefaultReader 進行讀取。(有關完整程式碼,請參閱我們的 簡單隨機流示例)。每個資料塊按順序讀取並作為 UTF-8 位元組陣列輸出到 UI,直到流讀取完畢,此時我們從遞迴函式返回,並將整個流列印到 UI 的另一部分。

js
function fetchStream() {
  const reader = stream.getReader();
  let charsReceived = 0;

  // read() returns a promise that fulfills
  // 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");
      para.textContent = result;
      return;
    }

    // value for fetch streams is a Uint8Array
    charsReceived += value.length;
    const chunk = value;
    let listItem = document.createElement("li");
    listItem.textContent = `Received ${charsReceived} characters so far. Current chunk = ${chunk}`;
    list2.appendChild(listItem);

    result += chunk;

    // Read some more, and call this function again
    return reader.read().then(processText);
  });
}

示例 2 - 按行處理文字

此示例展示瞭如何獲取文字檔案並將其作為文字行流進行處理。它處理了資料塊不以換行符結束,以及從 Uint8Array 轉換為字串的情況。

js
async function* makeTextFileLineIterator(fileURL) {
  const utf8Decoder = new TextDecoder("utf-8");
  let response = await fetch(fileURL);
  let reader = response.body.getReader();
  let { value: chunk, done: readerDone } = await reader.read();
  chunk = chunk ? utf8Decoder.decode(chunk, { stream: true }) : "";

  let re = /\r?\n/g;
  let startIndex = 0;

  for (;;) {
    let result = re.exec(chunk);
    if (!result) {
      if (readerDone) {
        break;
      }
      let remainder = chunk.substring(startIndex);
      ({ value: chunk, done: readerDone } = await reader.read());
      chunk =
        remainder + (chunk ? utf8Decoder.decode(chunk, { stream: true }) : "");
      startIndex = re.lastIndex = 0;
      continue;
    }
    yield chunk.substring(startIndex, result.index);
    startIndex = re.lastIndex;
  }
  if (startIndex < chunk.length) {
    // last line didn't end in a newline char
    yield chunk.substring(startIndex);
  }
}

for await (let line of makeTextFileLineIterator(urlOfFile)) {
  processLine(line);
}

規範

規範
Streams
# 預設讀取器的參考①

瀏覽器相容性

另見