一尘不染

node.js进程如何知道何时停止?

node.js

由于许多node.js脚本遵循异步执行模式(以下示例),因此它们如何知道何时停止?

在以下代码中,节点如何确定在处理writeFile和适当注册回调之后,在回调运行之前,该进程应保持活动状态?

fs = require('fs');

fs.writeFile('foo', 'cat', function() {
  console.log('wrote to foo!'); 
  fs.readFile('foo', 'utf8', function(err, data) {
    console.log(data);
  });
});

阅读 319

收藏
2020-07-07

共1个答案

一尘不染

节点跟踪所有未完成的工作请求。您的fs.writefile()调用为I / O创建工作请求,并将您的回调添加到该请求。节点在启动I /
O活动的同时将工作请求保存到其表中。到达函数末尾时,代码执行将退出。(但您的内存/变量/等仍然存在)

稍后,I / O完成,并且节点将工作请求从表中取出。它看到附加到请求的回调,因此使用I /
O请求的结果调用该函数。您的全局数据仍然存在,并且闭包中的任何变量仍然存在,因此在您的代码中似乎从未停止过。

如果您什么也不做,不要再发出任何请求,那么当您从函数返回时,节点将停止,因为这样队列中将不再有任何剩余的请求。

因此,节点“知道”继续运行,因为它跟踪其表中的活动工作请求,并且直到所有排队的工作都完成并且这些表为空时才会停止。

请注意,“排队工作”可能包括诸如等待计时器或等待网络数据到达之类的事情。您发出一个请求,要求您说“如果以后有事请给我打电话”。

setTimeout()也是一个工作请求(如果您斜视一下)。使用计时器,您知道会发生什么以及何时发生。使用setTimeout()只会发生一个“事情”。节点将仅对您的回调进行一次调用,然后“忘记”工作请求。相反,如果您使用setInterval(),则创建了一个持久性工作请求。节点将“保留”其表中的工作请求,并将反复调用回调,直到您取消该请求为止。

net.Server.listen()是另一个工作请求,它是一个持久性工作请求。您不知道何时调用回调或调用多少次,因为这取决于连接到服务器的远程客户端。节点将工作请求保持在其表中,直到您取消该请求为止。

2020-07-07