繁体   English   中英

节点读取流:什么时候进行流传输?

[英]Node read stream: when does the streaming happen?

这是一个代码示例,与您可以从网上获得的文档或文档没有太大不同:

var fs = require('fs');
var r = fs.createReadStream(process.argv[2], { encoding: 'utf8' });
r.on('data', function (chunk) {
    console.log("chunk: >>>" + chunk + "<<<");
});
r.on('end', function () {
    console.log("This is the end");
});

令我感到困惑的是:什么时候触发事件的流媒体发生? 显然,不是直接在读取流的构造上进行的,因为这将在到达on s之前完成,并且事件监听代码将永远不会执行(这是完美的)。

我担心的:有一个理论的机会,如果事件被错过on来电时为时已晚?

答案是否定的,在节点0.10.x和更高版本中是不可能的。 创建流时,它会暂停,因此无法dataend事件。 添加data侦听器(但不添加end侦听器)时,流将自动恢复。

还值得一提的是,在当前“滴答”结束之前不会发生任何IO,因此即使在同一滴答中附加data侦听器也总是安全的,即使对于较早的节点版本也是如此。 例如:

stream.resume();
stream.on('data', ...); // <- same tick, same javascript invocation = safe

stream.resume();
setImmediate(function () {
  stream.on('data', ...); // <- different tick, different javascript invocation = unsafe
});

这听起来可能令人困惑,但是在process.nextTick回调中添加侦听器也是安全的,因为它实际上是在CURRENT滴答之后立即在任何IO回调之前进行调用(这种情况确实很糟糕)。

想到这一点的最简单方法是,您提供的所有代码都被阻止,因此,如vkurchatkin所解释的那样,直到当前滴答结束为止,流上才能发生任何活动。 只有当当前滴答声的JavaScript执行完成时,流IO才能开始。

var fs = require('fs');
var r = fs.createReadStream(process.argv[2], { encoding: 'utf8' });
// Stream created in paused state, JS code is blocking IO

// We're still in the current tick so no IO could have occured since the above lines
r.on('data', function (chunk) {
  console.log("chunk: >>>" + chunk + "<<<");
});

// We're still in the current tick so no IO could have occured since the above lines
r.on('end', function () {
  console.log("This is the end");
});

// We've left the current tick so the internal IO code will now execute and call the bound events if necessary

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM