如何在Node.js中退出


Answers:


2373

调用全局process对象的exit方法:

process.exit()

从文档:

process.exit([code])

以指定的结束进程code。如果省略,则退出使用“成功”代码0

要以“失败”代码退出:

process.exit(1);

执行节点的外壳程序应将退出代码视为1


5
只想添加一些东西。如果您正在处理请求,那么您也应该也处理该请求end()。否则,它将挂起。
pixelfreak 2012年

126
@pixelfreak,exit完全没有误导。您对Node的工作方式感到困惑。将Node视为服务器本身。它不仅仅是根据需要启动的,就像PHP在Apache之类的Web服务器中一样。Node甚至根本不需要与Web服务器有任何关系!它只是一些JavaScript的宿主,还有一些漂亮的内置库可用来做有用的事情。
Brad 2012年

6
@Brad And PHP是一种通用语言。无需与mod_phpApache 一起运行或使用它。如果您确实想要或可以像在node中那样使用更合理/标准化的方法(如FastCGI),则可以像在node中那样重新实现PHP中的httpd。
宾基

38
请该说明process.exit()不建议,如在下面这个答案
AndreasPizsa

409

只是一个音符,使用process.exit([number])不推荐的做法。

调用process.exit()将强制进程尽快退出,即使仍有异步操作尚未完全完成,包括对process.stdout和process.stderr的I / O操作。

在大多数情况下,实际上没有必要显式调用process.exit()。如果事件循环中没有其他待处理的工作,则Node.js进程将自行退出。可以设置process.exitCode属性,以告知进程正常退出时要使用哪个退出代码。

例如,以下示例说明了process.exit()方法的滥用,它可能导致打印到stdout的数据被截断并丢失:

// This is an example of what *not* to do:
if (someConditionNotMet()) {
  printUsageToStdout();
  process.exit(1);
}

之所以有问题,是因为有时Node.js中对process.stdout的写入是异步的,并且可能在Node.js事件循环的多个滴答中发生。但是,调用process.exit()会强制该进程退出,然后再执行对stdout的其他写入操作。

该代码应该直接设置process.exitCode,而不是直接调用process.exit(),并通过避免为事件循环安排任何其他工作来允许进程自然退出:

// How to properly set the exit code while letting
// the process exit gracefully.
if (someConditionNotMet()) {
  printUsageToStdout();  
  process.exitCode = 1;
}

31
到目前为止,这是最好的答案。其他答案可能不允许节点在退出之前正确处理未决事件,非常可悲:(
djabraham

3
同意,这应该有更多的支持!我有一个通过shelljs.exec启动多个子进程的节点脚本,如果任何子进程失败,我希望我的总体脚本返回错误退出代码。process.exitCode = 1在exec回调中效果很好(而仅在其中调用process.exit(1)会在所有子进程完成之前退出主脚本!)
Nick

15
我使用此答案,发现我的过程从未真正退出过。必须按Ctrl-C组合键。
jcollum

33
立即处理和未决事件终止有很多用例。那正是process.exit()目的。
Dominic Cerisano

6
无论如何这都不是最好的答案,因为它不能回答问题。相反,它提供了有关如何为nodejs程序开发代码流的最佳实践。
anon58192932 '18年

365

从官方的nodejs.org文档中:

process.exit(code)

用指定的代码结束进程。如果省略,则退出使用“成功”代码0。

要以“失败”代码退出:

process.exit(1);

9
@Alison是的,或更确切地说是code = 0; process.exit(code);
2013年

7
是真的,如果您要退出,您可能根本不在乎的值code
Armand

8
@Alison一个更好的主意是process.exit()没有参数,因为代码默认为0
Jeremy Moritz

2
@Armand您是正确的-代码只是一个变量,在这种情况下,用于指示参数是什么。因此,.exit(0)可以完成示例中的所有操作。
Gerard ONeill 2014年

23
@Armand代码不适合您,适用于运行您的代码的任何对象。例如,如果使用创建一个exit_0.js process.exit(0);并运行它,node exit_0.js && echo 'success'它将显示“成功”。如果使用创建process.exit(1);并运行exit_1.js,node exit_1.js && echo 'success'它不会说“成功”,因为您的进程以非零值退出(这表示shell出现“失败”或“异常退出”)。另外,$?如果运行node exit_1.jsvs ,您将看到不同的值node exit_0.js(可以先检查node exit_1.js再做echo $?)。
msouth

276

如果您在Unix终端或Windows命令行中,并且想要退出Node REPL,请选择...

  • Ctrl+ C两次,或
  • 输入.exit并按Enter,或
  • 在行首按Ctrl+ D(仅限Unix)

14
请注意,除了Node之外,Mac或Linux上的Ctrl + D快捷键几乎可用于您将遇到的所有shell和REPL,包括Unix shell(如Bash),数据库shell(如MySQL和PostgreSQL)以及REPL(如编程语言)。 Python,PHP和Ruby。这是退出我曾经使用过的shell的唯一方法。
Mark Amery

2
对于nodeREPL,按Ctrl + D退出是一种标准行为,因此它也适用于Windows。
艾伦(Alan)

按Ctrl + C(即使在Mac上也是如此!)
王子


79

这取决于您愿意退出node.js进程的原因,但是无论如何,这process.exit()要考虑最后一个选择。来自文档的报价:

重要的是要注意,process.exit()即使仍有尚未完成的异步操作(包括到process.stdout和的I / O操作),调用也会迫使进程尽快退出process.stderr

在大多数情况下,实际上没有必要process.exit()显式调用 。如果事件循环中没有其他待处理的工作,则Node.js进程将自行退出。process.exitCode可以设置该 属性,以告知进程正常退出时要使用哪个退出代码。

让我们介绍一下您可能愿意退出node.js进程以及为什么应该避免的可能原因 process.exit()

情况1-执行完成(命令行脚本)

如果脚本已结束,并且节点解释器没有退出,则表明某些异步操作仍在等待处理。此时强行终止进程是错误的process.exit()。最好尝试了解阻止脚本以预期方式退出的原因。而当您解决此问题时,可以process.exitCode用来将任何结果返回给调用过程。

情况2-由于外部信号(SIGINT / SIGTERM / other)而终止

例如,如果您愿意正常关闭Express应用程序。与命令行脚本不同,Express App保持无限运行,等待新请求。process.exit()这将是一个不好的选择,因为它将中断所有正在处理的请求。其中一些可能是非幂等的(UPDATE,DELETE)。客户端永远不会知道这些请求是否在服务器端完成,这可能是客户端和服务器之间数据不一致的原因。唯一好的解决方案是告诉http服务器停止接受新请求,并等待未完成的请求完成server.close()

var express = require('express');
var app = express();
var server = app.listen(80);

process.on( 'SIGTERM', function () {
   server.close(function () {
     console.log("Finished all requests");
   });
});

如果仍然无法退出-请参阅案例1。

情况3-内部错误

throw出错总是比较好,您将获得格式正确的堆栈跟踪和错误消息。较高级别的代码始终可以决定是否可以处理错误(catch)或使其崩溃。另一方面,process.exit(1)它将以静默方式终止进程,并且没有机会从中恢复。它可能是的唯一“好处” process.exit(),您可以确定该过程将终止。


4
惊人的反应。Process.exit()对于大多数应用程序来说,这看起来像是大材小用。我一直在寻找与php的die()函数等效的函数……更像是:throw new Error('die msg')
AvadData

如果有人有一堆应该连续执行直到收到关闭请求的代码,那么是否存在用于注册事件的良好约定,该约定允许响应于关闭请求而放弃订阅,而无需使用事件的代码还是要求关闭的代码彼此之间有特定的了解?不幸的是,我想到某种实现的唯一方法是要求注册事件的任何代码段都还创建一个包装,其中包括一个用于注销该事件的闭包。
超级猫

26

REPL(命令行)

  • ctrl + c 两次

  • 键入.exit,然后按Enter

脚本文件

process.exit(code)

节点通常以代码0退出当没有其他异步操作挂起时,。

process.exit(1) 应该使用失败代码退出。这将允许我们推断该节点未正常关闭,而被迫关闭。

还有其他退出代码,例如

3-内部JavaScript解析错误(非常罕见)

5-v8 JavaScript引擎中的致命错误

9-无效的参数

有关完整列表,请参见节点退出代码


12

我有一个想要的应用程序:

  1. 向用户发送电子邮件
  2. 退出并显示错误代码

我必须挂接process.exit(code)exit事件处理程序,否则由于process.exit(code)直接调用会杀死异步事件,因此将不会发送邮件。

#!/usr/bin/nodejs
var mailer = require('nodemailer');
var transport = mailer.createTransport();
mail = {
  to: 'Dave Bowman',
  from: 'HAL 9000',
  subject: 'Sorry Dave',
  html: 'Im sorry, Dave. Im afraid I cant do <B>THAT</B>.'
}
transport.sendMail(mail);
//process.exit(1);
process.on('exit', function() { process.exit(1); });

4

记录一下:我一天中的大部分时间都在尝试使用process.exitCode自己正在构建的命令行工具(在Node v4.3.0上进行测试)为我工作。但是我无法让它表现得像文献记载的那样。commander尽管github.com/tj/commander.js/…让我感到奇怪,但这种情况本来可以算是一个边缘案例。不知道是否还有其他人在节点4上遇到了此问题,但是为了以防万一,以备将来参考。
mikermcneil

关于这种可能来自指挥官的问题,我还查看了它唯一的副手github.com/zhiyelee/graceful-readlink/…)但没有骰子。唯一可能的罪魁祸首似乎是:github.com/tj/commander.js/blob/… 特别是,问题在于,即使您设置了process.exitCode = 1,该过程
也会

10

正如@Dominic指出的那样,抛出未捕获的错误是更好的做法,而不是调用process.exit([code])
process.exitCode = 1; throw new Error("my module xx condition failed");


3
考虑到“如何在Node.js中退出”问题,这是可怕的建议。如果问题是专门询问如何从错误中退出,那么您的建议将更有意义。我强烈建议您以这样的方式来表达您的回答:仅当用户在出现错误的情况下试图退出应用程序时,才表明用户按照您的建议进行操作。
rstackhouse

@rstackhouse,我希望您已经抛出了一个未捕获的错误,该错误指向-> nodejs.org/api/process.html#process_process_exit_code
MANN

4
抛出的问题是丑陋的地狱堆栈跟踪。有什么技巧可以避免此堆栈跟踪(如果用法不正确,CLI工具要退出时不相关)?
MoOx

9

退出

let exitCode = 1;
process.exit(exitCode)

有用的退出代码

1-Catchall用于一般错误
2-滥用shell内置函数(根据Bash文档)
126-调用的命令无法执行
127-“找不到命令”
128-无效的参数退出
128 + n-致命错误信号“ n”
130-脚本被Control-C终止
255 \ *-退出状态超出范围

考虑更新您的答案,nodejs.org
api / process.html#

7

从代码中,您可以使用process.exit([errorcode])where [errorcode]是可选整数(0默认值表示成功)。

如果使用的是“ 读取Eval打印循环(REPL)”,则可以使用Ctrl+ D或键入.exit

另外,在Windows或Linux上,您可以使用Ctrl+ CCtrl+C

在Mac上,命令为Ctrl+ ZCtrl+Z


2
Mac上也有两个控制c的作品,至少在我的作品上也是如此 node --version v0.10.18
msouth

在Mac上,Control-C似乎没有取消已计划的操作,而ctrl-z会立即取消该进程。
jorisw

7

Ctrl + C两次或.exit

> 
(To exit, press ^C again or type .exit)
> 

3

通过键入,我能够使我的所有节点进程直接从Windows 10的Git Bash shell中消失taskkill -F -IM node.exe-这一次结束了我计算机上的所有节点进程。我发现我也可以使用taskkill //F //IM node.exe。不知道为什么都-//工作在这方面。希望这可以帮助!


那是由于taskkill本身。您正在杀死进程本身。同样,一个/就足够了。
Paul Stelian

2

由于流程是全局对象,因此无需导入任何模块。以下函数退出或终止当前节点进程。

process.exit(代码)

process.kill(process.pid)

process.abort()


1

打开运行节点应用程序的命令行终端,然后按Ctrl + C

如果您想从代码中退出节点js应用程序,

process.exit(); // graceful termination 
process.exit(1); // non graceful termination 


0

节点js的退出有两种方式:

  • 显式调用process.exit()
  • 或者,如果nodejs事件循环已完成所有任务,则无事可做。然后,节点应用程序将自动退出。

怎么运行的?

如果要强制执行循环停止该进程,则可以使用EventEmitter实例的全局变量process。因此,当您调用process.exit()时,您实际上会发出退出事件,该事件立即结束所有任务,即使仍有异步操作尚未完成。

process.exit()以退出代码(Integer)作为参数。代码0是默认值,这意味着它以“成功”退出。虽然代码1表示它以“失败”退出。


0

如果您使用的是Windows,请转至“任务管理器”,然后转至“进程”,查找一个名为“节点”的进程,然后用鼠标右键单击该进程,然后单击“结束进程”选项。


-1

您可以使用process.exit([code])函数。

如果要退出而不会出现“失败”,请使用代码0

process.exit(0);

要以“失败”代码退出,1您可以运行:

process.exit(1);

失败的“失败”代码特定于应用程序。因此,您可以使用自己的约定。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.