JS ReadableStream 类的使用详解

11 min read

ReadableStream 类是一种新的方式来处理流数据。它被设计成可重用的、基于流动(streaming)而不是基于缓存(buffering)的 API,适用于处理从网络、文件、以及其它来源的数据流。

以下是 JS ReadableStream 类的常见用法:

创建 ReadableStream

可以使用 ReadableStream 构造函数来创建一个新的 ReadableStream 对象。构造函数需要一个 object 类型参数,该对象包含下列可选属性:

  • start: 一旦流是开启,此函数就会被调用。 它接收一个 controller 参数,让你可以管理 flow 实例. 一旦你准备好开始流数据,你应该调用 controller.enqueue() 方法. 如果你无法产生任何数据,你应该以一个经过 reject() 的 promise 来结束该Promises-based API.

  • pull: 在需要读取更多数据时,此函数会被 StreamInstance.read() 方法调用(比如,当你调用 StreamInstance.getReader().read() 获取数据时).

  • cancel: 该函数会在需要取消数据流时调用。 它接收一个 reason 参数,使你可以向下游的资源发出一条消息,或者停止操作. 如果你实现了该函数,你应该避免在此函数内使用 throw 关键字,因为这会终止调用者的执行, 建议使用 return 直接结束运行,并传递取消成功的消息。如果你不想将任何消息传递给下游,你可以使用一个通过 Promise.resolve() 解决的 Promise。

下面是一个例子:

const myReadStream = new ReadableStream({
  start(controller) {
    controller.enqueue("Hello");
  },
  pull(controller) {
    controller.enqueue("World");
    controller.close();
  }
});

读取 ReadableStream

为了从 ReadableStream 中读取数据,可以使用 getReader() 方法获取 ReadableStreamDefaultReader 对象,并使用 read() 方法从 ReadableStream 中读取数据。

下面是一个例子:

const reader = myReadStream.getReader();
const myPromise = reader.read().then(({ value, done }) => {
  console.log(value);
  return reader.read();
});

上述代码首先获取了 ReadableStreamDefaultReader 实例 reader,然后通过调用 reader.read() 方法从 myReadStream 中读取数据,并将数据打印在控制台上。数据以对象的形式返回,该对象包含一个 value 属性,表示读取到的数据,和一个 done 属性,表示流是否已经关闭。

需要注意的是,ReadableStream 读取时是同步的,但是当读取数据完成时,read() 方法将返回一个 Promise,因为在读取 ReadableStream 的过程中可能会涉及到异步操作。

取消 ReadableStream

如果需要取消 ReadableStream,可以使用 cancel() 方法。该方法接受一个可选的参数 reason,类型为任何值,用于决定取消的原因。

下面是一个例子:

myReadStream.cancel('some reason').then(() => {
  console.log('stream has been cancelled!');
});

该代码将会从 myReadStream 流中取消所有未完成的操作,并在控制台上打印"stream has been cancelled!"。

总结

以上是 JS ReadableStream 类的一些常用方法和使用方式。ReadableStream 类是一个非常有用的类,可以方便地读取大量的流数据。但需要注意的是,它还是一个实验性功能,仍然在不断发展和完善中。遇到问题时,建议多查看文档和示例,尝试使用最新的 API 以及相关的 polyfills。