首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么process.stdin上的侦听器阻止节点终止?

为什么process.stdin上的侦听器阻止节点终止?
EN

Stack Overflow用户
提问于 2017-08-28 07:31:58
回答 3查看 1.9K关注 0票数 2

我是一个试图理解节点的Java程序员。对我来说没有意义的是,下面的代码如何防止进程终止?

代码语言:javascript
运行
复制
process.stdin.on('data', function(data) {
 console.log('Foobar');
        }
);

这就引出了许多问题,-:

  1. 如果有侦听器附加到任何东西或仅仅是全局流程对象,NodeJs会继续运行吗?
  2. 如果有附加的侦听器,NodeJs为什么不终止?
  3. 这是仅针对数据事件的行为吗?或者其他事件也会导致同样的行为?
  4. 节点进程可以避免终止的其他方法是什么?
EN

回答 3

Stack Overflow用户

发布于 2017-08-28 08:35:43

1.如果有侦听器附加到任何东西或只是全局进程对象,NodeJs会继续运行吗?

这与以下事实更相关:process.stdin正在创建一个更准确的socket,它是一个可读和可写的双工流,而且这也是一个EventEmitter类,因此当您将侦听器附加到process.stdin时,您打开套接字,等待在套接字中写入一些东西。

所以这里的问题不是EventEmitter's处理程序,而是等待end事件终止进程的流。

2.如果有附加的侦听器,为什么NodeJs不终止?

因为您打开了一个套接字连接,只有一个特殊的结束事件才会终止它。在您的示例中,当您发出终止命令时,它将终止,该命令将触发特殊的end事件CTRL+C

3.这是仅针对数据事件的行为吗?或者其他事件也会导致相同的行为吗?

对于process.stdin的所有事件,以及其他连接类型I/O.db连接,http请求等.

4.阻止节点进程终止的其他方法是什么?

  • 运行一个同步无限循环。
  • 打开插座,不要关闭它。

通过使用process.stdin.constructor附加process.stdin.constructor.toString()的源代码

代码语言:javascript
运行
复制
function ReadStream(fd, options) {
  if (!(this instanceof ReadStream))
    return new ReadStream(fd, options);
  if (fd >> 0 !== fd || fd < 0)    throw new errors.RangeError('ERR_INVALID_FD', fd);

  options = util._extend({
    highWaterMark: 0,
    readable: true,
    writable: false,
    handle: new TTY(fd, true)
  }, options);

  net.Socket.call(this, options);

  this.isRaw = false;
  this.isTTY = true;
}
票数 2
EN

Stack Overflow用户

发布于 2017-08-28 08:15:44

节点在完成其工作后退出。如果设置事件侦听器,它不会终止,因为它仍然有一个作业要运行--您的代码告诉我们,它必须侦听某种事件。因此,只要它是任何绑定到任何仍然存在的对象并可以调用的事件侦听器,它就会继续运行。如果发生退出事件,节点将为您清理所有内容。

票数 1
EN

Stack Overflow用户

发布于 2017-08-28 08:29:52

更新:

根据事件循环文件,从技术上讲:

Node.js检查是否在等待任何异步I/O或计时器,如果没有,则彻底关闭。

根据Node.js 流程文档:

通常,当没有安排工作时,Node.js进程将退出。

因此,Node.js是否会被终止取决于是否还有剩余的计划工作。

对于您的process.stdin.on('data'...示例,当代码完成执行时,仍然存在工作计划--用户输入应该被捕获和处理。因此,Node.js进程不会终止。

另一个例子是HTTP请求。如果Node.js发送一个HTTP请求(返回时间为30秒),则在检索和处理响应之前不会终止Node.js进程--除非完成所有计划的工作,否则Node.js进程将继续运行。

当然,无论计划的工作是否“完成”都是由Node.js定义的--在HTTP情况下,如果您只发送请求而不关心响应(没有响应处理程序),那么有两种方法可以将此计划工作定义为“完成”:发送了HTTP请求,仅此而已。发送HTTP请求并检索响应,无论有任何响应处理程序。Node.js选择策略B。

第三个例子是自定义事件及其事件侦听器。考虑以下代码:

代码语言:javascript
运行
复制
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
  console.log('an event occurred!');
});
myEmitter.emit('event');

当此代码执行完成时,尽管仍然存在事件侦听器,但Node.js进程将被终止,因为Node.js检测到不再存在计划中的工作--没有运行任何代码,也没有其他处理程序在等待,因此再也不会触发自定义事件。

因此,对于你的四个问题:

1.如果有侦听器附加到任何东西或只是全局进程对象,NodeJs会继续运行吗?

不仅仅是全局进程对象。对于侦听器来说,这取决于是否还有计划好的工作(是否可能触发侦听器)。

2.如果附加了侦听器,NodeJs为什么不终止?

JavaScript使用单线程模型,并使用事件循环处理各种动作逻辑。如果Node.js在主代码执行后终止,那么它只能用于编写非常小的程序。它将无法侦听用户操作/外部请求等。

3.这是仅针对数据事件的行为吗?或者其他事件也会导致同样的行为?

其他事件也可能导致同样的行为,这取决于该事件是否会触发预定的工作。

4.节点进程可以避免终止的其他方法是什么?

无论什么时候事件侦听器有可能在稍后被调用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45913868

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档