[可写流]和[可读流]都会在内部的缓冲器中存储数据,可以分别使用的 writable.writableBufferreadable.readableBuffer 来获取。

    可缓冲的数据大小取决于传入流构造函数的 highWaterMark 选项。 对于普通的流,highWaterMark 指定了[字节的总数][hwm-gotcha]。 对于对象模式的流,highWaterMark 指定了对象的总数。

    当调用 [stream.push(chunk)][stream-push] 时,数据会被缓冲在可读流中。 如果流的消费者没有调用 [stream.read()][stream-read],则数据会保留在内部队列中直到被消费。

    一旦内部的可读缓冲的总大小达到 highWaterMark 指定的阈值时,流会暂时停止从底层资源读取数据,直到当前缓冲的数据被消费 (也就是说,流会停止调用内部的用于填充可读缓冲的 readable._read())。

    当调用 [writable.write(chunk)][stream-write] 时,数据会被缓冲在可写流中。 当内部的可写缓冲的总大小小于 highWaterMark 设置的阈值时,调用 writable.write() 会返回 true。 一旦内部缓冲的大小达到或超过 highWaterMark 时,则会返回 false

    stream API 的主要目标,特别是 [stream.pipe()],是为了限制数据的缓冲到可接受的程度,也就是读写速度不一致的源头与目的地不会压垮内存。

    The highWaterMark option is a threshold, not a limit: it dictates the amount of data that a stream buffers before it stops asking for more data. It does not enforce a strict memory limitation in general. Specific stream implementations may choose to enforce stricter limits but doing so is optional.

    因为 [Duplex] 和 [Transform] 都是可读又可写的,所以它们各自维护着两个相互独立的内部缓冲器用于读取和写入, 这使得它们在维护数据流时,读取和写入两边可以各自独立地运作。 例如,[net.Socket] 实例是 [Duplex] 流,它的可读端可以消费从 socket 接收的数据,而可写端则可以将数据写入到 socket。 因为数据写入到 socket 的速度可能比接收数据的速度快或者慢,所以读写两端应该独立地进行操作(或缓冲)。