ReadableStreamBYOBReader: phương thức read()

Baseline 2026 *
Newly available

Since March 2026, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Some parts of this feature may have varying levels of support.

Note: This feature is available in Web Workers.

Phương thức read() của giao diện ReadableStreamBYOBReader được dùng để đọc dữ liệu vào một view trên buffer do người dùng cung cấp từ readable byte stream liên quan. Yêu cầu dữ liệu sẽ được đáp ứng từ các hàng đợi nội bộ của stream nếu có dữ liệu. Nếu các hàng đợi stream rỗng, yêu cầu có thể được cung cấp dưới dạng truyền zero-copy từ nguồn byte bên dưới.

Phương thức nhận một view trên buffer mà dữ liệu được đọc vào làm đối số, và trả về một Promise. Promise hoàn thành với đối tượng có thuộc tính valuedone khi dữ liệu có sẵn, hoặc khi stream bị hủy. Nếu stream gặp lỗi, promise sẽ bị từ chối với đối tượng lỗi liên quan.

Khi một chunk dữ liệu được cung cấp, thuộc tính value sẽ chứa một view mới. View này sẽ có cùng buffer/bộ nhớ backing (và cùng loại) như view gốc được truyền vào phương thức read(), nay chứa chunk dữ liệu mới. Lưu ý rằng sau khi promise hoàn thành, view gốc được truyền vào phương thức sẽ bị tách ra và không còn sử dụng được. Promise sẽ hoàn thành với value: undefined nếu stream đã bị hủy. Trong trường hợp này, vùng bộ nhớ backing của view bị loại bỏ và không được trả lại cho caller (tất cả dữ liệu đã đọc trước đó trong buffer của view bị mất).

Thuộc tính done cho biết có còn dữ liệu nào được mong đợi không. Giá trị được đặt là true nếu stream đã đóng hoặc bị hủy, và false trong các trường hợp khác.

Phương thức cũng có tham số tùy chọn options.min có thể dùng để chỉ định số phần tử tối thiểu phải có sẵn trước khi promise hoàn thành, trong khi stream đang hoạt động. View được trả về trong thuộc tính value sẽ luôn có ít nhất số phần tử này, trừ khi stream đóng lại.

Cú pháp

js
read(view)
read(view, options)

Tham số

view

View để đọc dữ liệu vào.

options Optional

Các tùy chọn như sau:

min

Số phần tử tối thiểu để đọc trước khi promise hoàn thành trong khi stream đang hoạt động. Nếu không được cung cấp, promise sẽ giải quyết với ít nhất một phần tử, tối đa kích thước của view. Con số này không được lớn hơn view đang được đọc vào.

Giá trị trả về

Một Promise, hoàn thành/bị từ chối với kết quả tùy thuộc vào trạng thái của stream. Đối tượng kết quả chứa hai thuộc tính, valuedone.

Các trường hợp có thể xảy ra:

  • Nếu một chunk có sẵn và stream vẫn đang hoạt động, done của kết quả là false, và value là một view chứa dữ liệu mới. View này có cùng loại và cùng bộ nhớ backing như view được truyền vào phương thức read(). view gốc sẽ bị tách ra và không còn sử dụng được.

  • Nếu stream đã đóng, done của kết quả là true, và value có các thuộc tính giống như trên.

  • Nếu stream bị hủy, done của kết quả là true, và valueundefined. Trong trường hợp này, bộ nhớ backing bị loại bỏ.

  • Nếu stream phát sinh lỗi, promise bị từ chối với lỗi liên quan.

Ngoại lệ

TypeError

Đối tượng nguồn không phải là ReadableStreamBYOBReader, stream không có chủ, view không phải là đối tượng hoặc đã bị tách ra, độ dài view là 0, options.min là 0, hoặc ReadableStreamBYOBReader.releaseLock() được gọi (khi có yêu cầu đọc đang chờ).

RangeError

Giá trị options.min lớn hơn view đang được ghi vào.

Ví dụ

Đọc vào một view

Mã ví dụ ở đây được lấy từ các ví dụ trực tiếp trong Sử dụng readable byte streams.

Đầu tiên chúng ta tạo reader bằng cách dùng ReadableStream.getReader() trên stream, truyền mode: "byob" trong tham số tùy chọn. Chúng ta cũng cần tạo một ArrayBuffer, là "bộ nhớ backing" của các view mà chúng ta sẽ ghi vào.

js
const reader = stream.getReader({ mode: "byob" });
let buffer = new ArrayBuffer(4000);

Hàm sử dụng reader được hiển thị bên dưới. Hàm này gọi đệ quy phương thức read() để đọc dữ liệu vào buffer. Phương thức nhận một Uint8Array typed array là view trên phần của array buffer gốc chưa được ghi vào. Các tham số của view được tính từ dữ liệu nhận được trong các lần gọi trước, xác định offset vào array buffer gốc.

js
readStream(reader);

function readStream(reader) {
  let bytesReceived = 0;
  let offset = 0;

  while (offset < buffer.byteLength) {
    // read() returns a promise that fulfills when a value has been received
    reader
      .read(new Uint8Array(buffer, offset, buffer.byteLength - offset))
      .then(function processBytes({ done, value }) {
        // Result objects contain two properties:
        // done  - true if the stream has already given all its data.
        // value - some data. 'undefined' if the reader is canceled.

        if (done) {
          // There is no more data in the stream
          return;
        }

        buffer = value.buffer;
        offset += value.byteLength;
        bytesReceived += value.byteLength;

        // Read some more, and call this function again
        // Note that here we create a new view over the original buffer.
        return reader
          .read(new Uint8Array(buffer, offset, buffer.byteLength - offset))
          .then(processBytes);
      });
  }
}

Khi không còn dữ liệu trong stream, phương thức read() hoàn thành với đối tượng có thuộc tính done được đặt là true, và hàm trả về.

Đọc số phần tử tối thiểu

Ví dụ này gần giống với ví dụ trước, ngoại trừ chúng ta đã sửa đổi mã để đọc tối thiểu 101 phần tử trong mỗi lần lặp.

Chúng ta cũng đã biến nó thành ví dụ trực tiếp. Lưu ý rằng hầu hết mã không liên quan đến ví dụ và do đó bị ẩn. Để biết thêm thông tin, xem Sử dụng readable byte streams.

JavaScript

js
function readStream(reader) {
  let bytesReceived = 0;
  let offset = 0;

  while (offset < buffer.byteLength) {
    // read() returns a promise that resolves when a value has been received
    reader
      .read(new Uint8Array(buffer, offset, buffer.byteLength - offset), {
        min: 101,
      })
      .then(async function processText({ done, value }) {
        // Result objects contain two properties:
        // done  - true if the stream has already given all its data.
        // value - some data. Always undefined when done is true.

        if (done) {
          logConsumer(
            `readStream() complete. Read ${value.byteLength} bytes (total: ${bytesReceived})`,
          );
          return;
        }

        buffer = value.buffer;
        offset += value.byteLength;
        bytesReceived += value.byteLength;

        // logConsumer(`Read ${bytesReceived} bytes: ${value}`);
        logConsumer(`Read ${value.byteLength} bytes (total: ${bytesReceived})`);
        result += value;

        // Read some more, and call this function again
        return reader
          .read(new Uint8Array(buffer, offset, buffer.byteLength - offset), {
            min: 101,
          })
          .then(processText);
      });
  }
}

Kết quả

Nhật ký từ nguồn push bên dưới (trái) và consumer (phải) được hiển thị bên dưới. Lưu ý rằng nếu trình duyệt hỗ trợ đối số options.min thì ít nhất 101 phần tử được trả về mỗi lần (và thường nhiều hơn), trừ khi stream đóng lại.

Thông số kỹ thuật

Specification
Streams
# byob-reader-read

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

Xem thêm