为什么Node中的server.listen不会返回到shell

4

Node文件可以描述从服务器到简单脚本,甚至只是打印到控制台的内容:

//logger.js
console.log('Hello World');

// in the terminal
> node logger.js
Hello World
>

http包(以及其他包)如何不将命令提示符返回给用户;它们如何保持进程活动?

//server
require('http').createServer(function (req, res) {
  res.end('Hello World');
}).listen(3000);

// in the terminal
> node server.js
// process stays in the foreground, no prompt back

从您对答案的评论中,听起来您想要构建一个表现出这种行为的东西。通常,如果仍然有一些操作正在进行(服务器正在监听,setTimeout 等待等),这将自动发生。那么是什么让您应该保持进程运行但实际上没有呢? - Aaron Dufour
@AaronDufour 这样就容易理解它是如何工作的了 ;-) - yves amsellem
3个回答

6

如果有一个正在监听的套接字,Node将不会退出。这就是TL;DR答案。(其他回答中谈到事件队列是程序无法退出的可能原因是正确的,但这与server.listen()无关。)

在幕后,http.createServer()最终会调用server.listen() 调用server.listen()将阻止进程退出,因为server.listen()会创建一个套接字。请注意来自socket.ref()文档的内容:

与unref相反,对先前未引用的套接字调用ref将不允许程序退出,如果它是唯一剩下的套接字(默认行为)。如果套接字已被引用,则再次调用ref将不起作用。

以及socket.unref()

在套接字上调用unref将允许程序退出,如果这是事件系统中唯一活动的套接字。如果套接字已经被取消引用,则再次调用取消引用将不起作用。

如果你想进一步深入,我相信你需要深入C或C++,这是Node.js/io.js的基础。


5

当事件队列中没有事件且没有后台任务(可以向事件队列添加事件)时,Node将退出,在您的情况下,是后者。


那么,模拟http.createServer并保持手动控制的最简单方法是什么? - yves amsellem
如在我的问题中:让进程在前台运行,不返回提示。 - yves amsellem
你真的相信 http.createServer 是那样编写的吗? - yves amsellem
1
不,你要问如何像http一样“行动”,并保持运行状态。对于http.createServer,你可以随时查看代码。 - user2786771
我问了一下http.createServer是如何工作的。顺便说一句,在这里大多数问题你总可以“读代码”,但对于其他人的解释可能更快更简单。 - yves amsellem
显示剩余2条评论

0

@user2786771 是真的。

更详细的解释可以在这篇文章中找到。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接