ReadableStreamBYOBReader

可用性有限

此特性不是基线特性,因为它在一些最广泛使用的浏览器中不起作用。

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

ReadableStreamBYOBReader 接口是 Streams API 的一部分,它定义了一个用于 ReadableStream 的读取器,该读取器支持从底层字节源进行零拷贝读取。它可用于从数据以“匿名”字节序列形式提供的底层源(例如文件)进行高效复制。

通常应该通过在流上调用 ReadableStream.getReader() 来获取此读取器类型的实例,并在选项参数中指定 mode: "byob"。可读流必须具有底层字节源。换句话说,它必须在 构造 时使用 type: "bytes" 指定了底层源。

使用此类读取器时,当可读流的内部队列为空时发起的 read() 请求将导致从底层源进行零拷贝传输(绕过流的内部队列)。如果内部队列不为空,read() 将从缓冲的数据中满足请求。

请注意,此读取器的方法和属性与默认读取器(ReadableStreamDefaultReader)的方法和属性类似。read() 方法的区别在于它提供了写入数据的视图。

构造函数

ReadableStreamBYOBReader()

创建并返回一个 ReadableStreamBYOBReader 对象实例。

实例属性

ReadableStreamBYOBReader.closed 只读

返回一个 Promise,当流关闭时该 Promise 将 fulfilled,或者在流抛出错误或读取器的锁被释放时 reject。此属性使您能够编写响应流结束的代码。

实例方法

ReadableStreamBYOBReader.cancel()

返回一个 Promise,当流被取消时解析。调用此方法表示消费者对该流不再感兴趣。提供的 reason 参数将传递给底层源,源可能会也可能不会使用它。

ReadableStreamBYOBReader.read()

传递一个必须写入数据的视图,并返回一个 Promise,该 Promise 将解析为流中的下一个块,或 reject 并指示流已关闭或出错。

ReadableStreamBYOBReader.releaseLock()

释放读取器对流的锁定。

示例

下面的示例摘自 使用可读字节流 中的实时示例。

首先,通过在流上调用 ReadableStream.getReader() 并指定选项参数中的 mode: "byob" 来创建读取器。由于这是一个“自带缓冲区”读取器,我们还需要创建一个 ArrayBuffer 来读取数据。

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

下面是一个使用该读取器的函数。它递归调用 read() 方法将数据读取到缓冲区中。该方法接受一个 Uint8Array 类型化数组,该数组是原始数组缓冲区中尚未写入部分的可视化视图。视图的参数是根据先前调用中接收到的数据计算的,这些数据定义了原始数组缓冲区的偏移量。

js
readStream(reader);

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

  // read() returns a promise that resolves when a value has been received
  reader
    .read(new Uint8Array(buffer, offset, buffer.byteLength - offset))
    .then(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. Total bytes: ${bytesReceived}`);
        return;
      }

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

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

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

当流中没有更多数据时,read() 方法将解析为一个属性 done 设置为 true 的对象,然后函数返回。

ReadableStreamBYOBReader.closed 属性返回一个 Promise,可用于监视流的关闭或错误,或者读取器锁的释放。

js
reader.closed
  .then(() => {
    // Resolved - code to handle stream closing
  })
  .catch(() => {
    // Rejected - code to handle error
  });

要取消流,请调用 ReadableStreamBYOBReader.cancel(),可以选择指定一个原因。这将返回一个 Promise,当流被取消时该 Promise 将解析。当流被取消时,控制器将依次调用底层源上的 cancel(),并将可选原因传递进去。

使用可读字节流 中的示例代码会在按钮被按下时调用 cancel 方法,如下所示。

js
button.addEventListener("click", () => {
  reader.cancel("user choice").then(() => console.log("cancel complete"));
});

消费者还可以调用 releaseLock() 来释放读取器对流的持有,但前提是没有待处理的读取。

js
reader.releaseLock();

规范

规范
Streams
# byob-reader-class

浏览器兼容性

另见