Stream API - 基础



Stream API 允许开发人员访问通过网络接收的数据流,并在 JavaScript 编程语言的帮助下根据自己的需要逐点处理它们。其中,流是我们想要通过网络以小块形式接收的数据序列,然后我们逐点处理这些小块数据。

在流式传输之前,如果我们想处理视频、音频或文本文件,我们需要从网络下载该完整文件并等待它被反序列化为指定格式,然后处理完整的下载文件。

引入流后,整个工作文化发生了变化,现在我们可以在客户端使用 JavaScript 接收到数据后立即开始逐点处理数据,而无需创建任何额外的缓冲区或 blob。使用流,我们可以执行各种任务,例如可以找到流的起点和终点,或者可以将流链接在一起,或者可以轻松处理错误,可以取消流等等。

流式处理用于创建现实世界的应用程序,例如 Netflix、Amazon Prime Videos、Zee5、Voot、YouTube 等视频流应用程序。这样用户就可以轻松地在线观看电影、电视节目等,而无需下载它们。Stream API 提供了各种功能,如 ReadableStream、Teeing、WritableStream、Pipe Chains、Backpressure、内部队列和排队策略。让我们一一详细讨论它们。

可读流

可读流允许您使用 ReadableStream 对象从 JavaScript 中的源读取数据/块。块是读取器将按顺序读取的小块数据。它可以是单个位的,也可以是大尺寸(如类型化数组等)。要读取可读流,API 请提供读取器。它从流中读取数据块,然后处理该数据块的数据。一次只有一个读取器可以读取流,不允许其他读取器读取该流。

Stream Basic

可写流

可写流允许您使用 Writable Stream 对象在 JavaScript 中写入数据。数据由写入器写入流。写入器以块的形式写入数据(一次一个块)。当创建写入器并开始写入流时,该写入器的流将被锁定,并且不允许其他写入器访问该流,并且使用队列间来跟踪写入器写入的块。

Stream Basic

Teeing

Teeing 是一个过程,在这个过程中,流被拆分为流的两个相同副本,以便两个单独的读取器可以同时读取流。我们可以在 ReableStream.tee() 方法的帮助下实现 teeing。此方法返回一个数组,该数组包含指定流的两个相同副本,并且可以由两个读取器读取。

发球

管道链

Pipe Chain 是一个将多个流连接在一起以创建数据处理流的过程。在 Stream API 中,我们可以借助管道链结构将一个流通过管道传输到另一个流中。管道链的起点称为原始源,管道链的最后一个点称为最终凹陷。

要管道流,我们可以使用以下方法 -

  • ReadableStream.pipeThrough() − 此方法用于通过转换流传输当前流。Transform stream 包含一对可读和可写的流。
  • ReadableStream.pipeTo() − 此方法用于将当前 ReadableStream 通过管道传输到指定的 WritableStream,并将返回一个 Promise,当管道过程成功完成或由于某些错误而被拒绝时,该 Promise 会解决。

管道链

背压

背压(Backpressure)是 Stream API 中的一个特殊概念。在此过程中,单个流或管道链控制读/写的速度。假设我们有一个流,这个流很忙,无法获取新的数据块,所以它通过链向后发送一条消息,告诉转换流放慢块的交付速度,这样我们就可以避免瓶颈。

我们可以在 ReadableStream 中使用背压,因此我们需要在 ReadableStreamDefaultContriller.desiredSize 属性的帮助下找到消费者所需的块大小。如果块大小非常小,则 ReadableStream 可以指示它是底层源,因此请停止发送更多数据并随流链一起发送背压。

当消费者再次想要接收到的数据时,我们使用 pull 方法告诉底层源将数据发送到流中。

内部队列和排队策略

Internal queues (内部队列) 是跟踪尚未处理或完成的 chunk 的队列。例如,在可读流中,内部队列会跟踪那些存在于 enqueue 上但尚未读取的块。内部队列使用排队策略,表示背压信号如何根据内部队列状态发送。

结论

所以这些是 Stream API 的基本概念。它通常用于在线流媒体。当您在线观看视频时,浏览器或应用程序会在后台接收连续的数据块流,然后由该浏览器或应用程序处理这些数据块以显示视频。现在在下一篇文章中,我们将了解 Stream API 的 Readable 流。