背景:https://github.com/Almenon/AREPL-vscode/pull/332(很多,我建议先阅读下面的内容)
我假设到达highWaterMark时节点刷新标准输出。它是否正确?根据此stackoveflow,答案似乎是肯定的。假设这样,如果超出了高水位线,则多余的字符应该再次刷新,对吧?
Node似乎忽略了高水位标记,并且仅冲洗一次,而不管缓冲区大小如何。
示例代码以预期/实际结果重现了我的问题:
import { spawn } from "child_process"
// 8192*2 (16384 aka 16KB) is the highWaterMark (aka buffer size?)
const node_process = spawn("node", ["-e", "process.stdout.write('a'.repeat(8192*2+1));setTimeout(()=>{console.log('done')},4000)"])
node_process.on('error', err => console.error(err))
let numFlushes = 0
node_process.stdout.on('data', (buffer: Buffer) => {
numFlushes += 1
const str = buffer.toString()
console.log(`flush number: ${numFlushes}\
Buffer length: ${buffer.length}`)
if (buffer.length < 20) console.log(str)
})
/*
Expected result: 3 flushes, one when highWaterMark is reached, another with rest of stdout, final with done log
Acutal result: 2 flushes. All of stdout is recieved at once. 4 seconds later comes the done log.
Related docs: https://nodejs.org/docs/latest-v12.x/api/stream.html#stream_buffering
OUTPUT (courtesy of quokka)
flush number: 1 Buffer length: 16385
at `flush number: ${ numFlushes }\ Buff... personal/test_node_buffer.ts:11:4
flush number: 2 Buffer length: 11
at `flush number: ${ numFlushes }\ Buff... personal/test_node_buffer.ts:11:4
done
at str personal/test_node_buffer.ts:13:8
*/
https://gist.github.com/Almenon/6286ca1baf0714b56dc133e03728eb12
我已经在Windows 10上对此进行了测试。在Linux上,如果您执行* 8 + 2,则按预期有3次刷新。奇。除此之外,这两个平台具有相同的行为。