ReadableStreamDefaultReader: read() method

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020.

Note: This feature is available in Web Workers.

read() của ReadableStreamDefaultReader trả về một Promise cung cấp quyền truy cập tới khối dữ liệu tiếp theo trong hàng đợi nội bộ của luồng.

Cú pháp

js
read()

Tham số

Không có.

Giá trị trả về

Một Promise, được hoàn tất/bị từ chối tùy theo trạng thái của luồng. Các khả năng khác nhau như sau:

  • Nếu có sẵn một khối dữ liệu, promise sẽ được hoàn tất với một đối tượng có dạng { value: theChunk, done: false }.
  • Nếu luồng được đóng, promise sẽ được hoàn tất với một đối tượng có dạng { value: undefined, done: true }.
  • Nếu luồng phát sinh lỗi, promise sẽ bị từ chối với lỗi tương ứng.

Ngoại lệ

TypeError

Đối tượng nguồn không phải là ReadableStreamDefaultReader, luồng không có chủ sở hữu, hoặc ReadableStreamDefaultReader.releaseLock() được gọi khi vẫn còn một yêu cầu đọc đang chờ.

Ví dụ

Ví dụ 1 - ví dụ đơn giản

Ví dụ này cho thấy cách dùng API cơ bản, nhưng không xử lý các phức tạp như việc các khối dữ liệu của luồng không kết thúc đúng ở ranh giới dòng, chẳng hạn.

Trong ví dụ này, stream là một ReadableStream tùy biến đã được tạo trước đó. Nó được đọc bằng một ReadableStreamDefaultReader được tạo bằng getReader(). (xem ví dụ stream ngẫu nhiên đơn giản của chúng tôi để biết mã đầy đủ). Mỗi khối dữ liệu được đọc tuần tự và xuất ra giao diện người dùng dưới dạng một mảng byte UTF-8, cho đến khi luồng đọc xong, tại thời điểm đó chúng ta thoát khỏi hàm đệ quy và in toàn bộ luồng sang một phần khác của giao diện người dùng.

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);
  });
}

Ví dụ 2 - xử lý văn bản theo từng dòng

Ví dụ này cho thấy cách bạn có thể tìm nạp một tệp văn bản và xử lý nó như một luồng các dòng văn bản. Nó xử lý trường hợp các khối dữ liệu của luồng không kết thúc ở ranh giới dòng, và việc chuyển đổi từ Uint8Array sang chuỗi.

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);
}

Thông số kỹ thuật

Specification
Streams
# ref-for-default-reader-read①

Tương thích trình duyệt

Xem thêm