我将使用以下代码说明问题。
child.js :
process.stdin.resume();
process.stdin.on('data', function(data) {
process.stdout.write(data + '\n');
process.stdout.write('world\n');
process.stdout.write('greatings, earthlings!\n');
});
parent.js :
var spawn = require('child_process').spawn;
var child = spawn('node', ['child.js']);
child.stdin.write('hello');
child.stdout.on('data', function(data) {
process.stdout.write('child echoed with: ' + data);
});
在 Windows cmd 中,我运行
node parent.js
输出:
child echoed with: hello
child echoed with: world
greatings, earthlings!
在这里,我确实在每个孩子的stdout 上绑定了数据事件,然后我会以“孩子用数据回应”的模式回显。 如您所见,在输出的第三行,它不是那种模式。那为什么呢?
我假设一次写入会触发一个数据事件(是吗?)。
所以我试图表明数据事件回调函数何时结束。
我改变了我在 parent.js 中绑定数据事件的方式:
child.stdout.on('data', function(data) {
process.stdout.write('child echoed with: ' + data);
process.stdout.write('callback ends\n');
});
我得到了这个输出:
child echoed with: hello
callback ends
child echoed with: world
greatings, earthlings!
callback ends
结果是三次写入,只有两个数据事件被触发?
为什么会发生这种情况?
答案 0 :(得分:0)
stream
只是一个字节流,因此假设write
次呼叫数与data
次事件数之间存在任何关联是不安全的。对于标准实现和使用,很可能它们将接近相同,但这取决于您编写数据的速度以及您正在编写的数据量。例如,一次写入调用可能会为每个写入的字节触发data
事件,或者在write
发出之前可以缓冲一些data
次调用。
要明确的是,您的案例中发生了什么:
process.stdout.write(data + '\n');
// Emits 'data' event with "hello\n"
process.stdout.write('world\n');
// Doesn't emit 'data' because it is buffered somewhere.
process.stdout.write('greatings, earthlings!\n');
// Emits 'data' event with "world\ngreatings, earthlings!\n"
因此第二个事件有两个行。这意味着当你运行
process.stdout.write('child echoed with: ' + data)
您正在打印所看到的内容:
child echoed with: world\ngreatings, earthlings!\n
呈现为
child echoed with: world
greatings, earthlings!