我正在阅读流文档,并在https://nodejs.org/api/stream.html#stream_buffering上寻找有关流的缓冲行为描述
该文件似乎没有提到inputStream缓冲区(或缓冲区?)会发生什么,当管道到多个输出时,不同的输出具有不同的消耗速度:
在管道多个输出时,readableStream是否为每个输出保留专用缓冲区?
消费时输出是否保持相同的速度,或者更快的结束更早?
const input = fs.createReadStream('img.jpg');
const target1 = input.pipe(fs.createWriteStream('target1.jpg'));
const target2 = input.pipe(fs.createWriteStream('target2.jpg'));
TL; DR:简短的答案是 - 较慢的目标流控制流速。
首先让我们看看读取方面会发生什么。
const input = fs.createReadStream('img.jpg');
当您实例化输入流时,它将以暂停模式创建并安排读取(不会同步读取,因此它不会访问该文件)。该流的highWaterMark
设置为类似于16384
,目前有一个0字节的缓冲区。
const target1 = input.pipe(fs.createWriteStream('target1.jpg'));
const target2 = input.pipe(fs.createWriteStream('target2.jpg'));
现在,当您实际将其传输到可写流时,通过在on('data')
中添加pipe method implementation - see the source事件处理程序来设置流动模式。
完成后我假设没有更多程序要运行,因此节点启动实际读取并在上面的处理程序中运行计划代码,该代码只是写入通过的任何数据。
当任何目标有更多的数据要写入时,流量控制就会发生,而highWaterMark
将write
操作返回false
。然后由calling pause here in the code停止阅读。在此之上的两行你会看到state.awaitDrain增加了。
现在读取流再次是paused
,可写流正在将字节写入磁盘 - 在某些时候缓冲级别再次低于highWaterMark
。在这一点上,drain
事件被解雇了executes this line,并且在所有等待的排水管被召唤之后,恢复流动。这是通过检查递减的awaitDrain
属性是否已达到零来完成的,这意味着已经调用了所有等待的排出事件。
在上面的例子中,两个流中较快的一个可以在写入时返回一个假值,但它肯定会排在第一个。如果不是awaitDrain
,则更快的流将恢复数据流,这将导致两者中较慢的缓冲区溢出。