为啥 data 事件只会阻止 NodeJS 运行时退出?
Posted
技术标签:
【中文标题】为啥 data 事件只会阻止 NodeJS 运行时退出?【英文标题】:Why does the data event only stop the NodeJS run time from exiting?为什么 data 事件只会阻止 NodeJS 运行时退出? 【发布时间】:2018-02-05 13:58:59 【问题描述】:在nodejs-中取如下代码:
console.log("Hello world");
process.stdin.on('connect', function()
);
这会打印 Hello World 然后节点退出。但是当我用“数据”事件替换连接事件时,节点运行时不会退出。
这是为什么呢? EventEmitter 的数据事件有什么特别之处?它是否打开套接字连接?所以在 on() 方法中有如下代码 -:
function on(event, callback)
if(event === 'data')
//open socket
//do work
else
//do non-socket work
是否有一个明确的答案来解释为什么向数据事件添加监听器“神奇地”打开一个套接字。
【问题讨论】:
“数据”事件没有什么特别之处。这是一个与任何其他事件一样的事件。 @ralphtheninja 太好了。那为什么当我们为数据事件附加监听器时nodejs运行时不退出,但当我们为任何其他事件附加监听器时退出 很难说。如果您能显示更多代码,那就太好了。 @ralphtheninja 我正在学习 Node.js。这就是我拥有的所有代码。只需将其粘贴并执行即可。然后将连接切换到数据并查看行为差异 哦,对了。这很可能是process.stdin
的实现细节。
【参考方案1】:
Node.js 事件循环有几个处理阶段,在您的情况下是 poll
阶段。例如传入数据(process.stdin.on('data', cb)
)的处理,所以直到有一个可以处理这个事件的回调,一个这个事件可能发生,节点事件循环不为空并且节点不会退出。
process.stdin
是具有休闲事件的可读流:
所以没有像connect
这样的东西。
process.stdin.on('readable', function()
console.log('Readable');
);
上面的代码将打印Readable
并退出,因为在触发事件流后,它不处于flowing
状态,因此它将退出事件循环,因为它是空的,但是data
事件将流状态设置为flowing
,
因此,如果流状态设置为flowing
,并且如果readableState.reading
是true
,它将阻止节点退出。
如果你这样做了
process.stdin.on('data', function(data)
console.log(data.toString());
);
如果您在运行时在控制台中编写任何内容,它将像 echo 一样工作。
https://github.com/nodejs/node/blob/master/lib/_stream_readable.js#L774-L795
您可以在此处阅读完整说明事件循环的工作原理https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/
【讨论】:
从您的回答中我无法理解的是,当我附加一个侦听器时,它为什么要等待接收数据?当我不附加监听器时,什么也没有发生,那么轮询阶段会消失吗?像 fs.readFile 这样的函数实际上做了一些工作然后调用回调,但是为数据事件附加一个监听器什么都不做。那还等什么呢? 还有哪些事件属于poll阶段,哪些事件属于timer阶段。我想我是从错误的角度看待这个问题。能否请您补充一下如何编写 Node 程序的直觉。 那么设置为“流动”的流会阻止节点退出吗? 您可能希望将其添加到您的答案中。【参考方案2】:如果我们假设 index.js
包含
process.stdin.on('data', console.log)
然后你输入node index.js
,然后进程等待stdin
上的输入。
如果您通过例如在标准输入上发送一些数据echo woohoo | node index.js
然后缓冲区将被写入并退出进程。
【讨论】:
以上是关于为啥 data 事件只会阻止 NodeJS 运行时退出?的主要内容,如果未能解决你的问题,请参考以下文章