WritableStream.write背后的机制和Node中的数据事件

时间:2014-03-15 04:34:07

标签: node.js events stream

我将使用以下代码说明问题。

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

结果是三次写入,只有两个数据事件被触发?

为什么会发生这种情况?

1 个答案:

答案 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!