Node.js 中的 readable.push(chunk[, encoding]) 函数

2025 年 4 月 30 日 | 阅读 4 分钟

Node.js 中 readable 的 push(chunk[, encoding]) 函数是 Streams API 中用于处理可读流 (Readable Streams) 的重要函数之一。Node.js 中的流 (Streams) 允许开发人员通过将大型数据输入分解成更易于管理的数据块来高效地处理它们,从而提供了一种更有效、异步且内存效率更高的数据处理方式。可读流中的 push 方法对于控制流中的数据发送至关重要,无论是基于事件还是自定义逻辑。

理解 Node.js 流

要理解 readable.push(chunk[, encoding]) 函数的可用性,了解 Node.js 流 (Streams) 的基本概念会很有帮助。流是使数据能够以连续流的形式被读取和写入的对,通常是分块而不是一次性全部处理。这对于处理大型数据源(如文件、网络请求或数据库查询)尤其有用,因为如果一次性加载,这些数据源可能会因为太大而难以在内存中舒适地处理。

在 Node.js 中,流主要分为四大类:

  • 可读流 (Readable): 可以从中读取数据的流(例如,读取文件)。
  • 可写流 (Writable): 可以向其写入数据的流(例如,写入文件)。
  • 双工流 (Duplex): 既可读又可写的流(例如,套接字)。
  • 转换流 (Transform): 双工流,它们在读取或写入数据时会修改或转换数据(例如,文件压缩流)。

可读流和 readable.push(chunk[, encoding])

readable.push(chunk[, encoding]) 方法用于手动将数据块推送到可读流的读取队列中。这在实现自定义可读流时非常有用,因为您可以精确地决定何时以及如何使数据可供流的消费者使用。

push 方法的工作原理如下:

  • chunk: 要推送到流读取队列中的数据。chunk 可以是 Buffer、字符串或 null。
  • encoding (可选): 如果 chunk 是字符串,则为其指定编码(例如 'utf8'、'ascii' 等)。如果 chunk 是 Buffer,或者流处于对象模式,则忽略此参数。

push 函数的返回值是 true 或 false,它指示流的 Buffer 是否已超出高水位标记。如果 push 返回 false,则表示内部 Buffer 已满,在它被清空之前不应再向其中推送数据;这样可以节省内存。

readable.push(chunk[, encoding]) 的关键点

关于 Node.js 中 readable.push() 函数有几个关键点如下:

  • 手动控制: push 允许开发人员控制何时以及如何将数据输入可读流,这对于自定义流实现非常有用。
  • 缓冲区管理: 通过观察 push 的返回值,您可以监控流的缓冲区并避免过多的内存使用。
  • 对象模式: 如果流处于对象模式(即它被设置为支持非字符串、非 buffer 的对象),您可以将任何 JavaScript 对象推送到其中,而无需指定编码。
  • 数据结束: 推送 null 到流中表示数据结束,之后将不再从流中消耗任何数据。

使用 readable.push(chunk[, encoding]) 的示例

让我们来看一个示例来演示 Node.js 中的 readable.push(chunk[, encoding]) 函数。这个可读流将通过向其中推送固定数量的块来手动生成其数据,并通过推送 null 来发出完成信号。

输出

readable.push(chunk[, encoding]) function in Node.js

说明

在此示例中

  • CustomReadableStream 类继承自 Readable,并实现了 _read() 方法。在实现自定义可读流时,_read 方法是必需的。
  • 在每次调用 _read 时,我们都会推送一个新的数据块,直到达到 maxChunks。一旦达到此限制,就会调用 push(null) 来发出流结束的信号。
  • customStream 上的 data 事件会处理每个被推送到可读流的块。

readable.push(chunk[, encoding]) 的实际用例

Node.js 中 readable.push() 函数的几个实际用例如下:

  • API 或数据库数据流: 在通过 API 或数据库获取数据时,开发人员可能更愿意在每次响应或数据批次到达时将其推入。当您事先不知道数据大小,或者数据是动态生成或获取的时,这非常有用。
  • 模拟实时数据: 在聊天应用或实时仪表盘等实时应用程序中,数据可能会作为实时事件的响应而生成。使用 push 函数将这些事件添加到可读流中,这提供了一种非常高效的处理实时数据的方式。
  • 文件处理: 当逐行或逐块读取文件时,在读取每个行或块时将其推送,可以对内存使用和处理流程进行细粒度控制。
  • 对象流: 对于非 buffer、非字符串数据,对象流在处理 JavaScript 对象时非常有用。