Cet article vous présentera quelques méthodes pour déclencher activement la fin du processus Node. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il sera utile à tout le monde.
Il existe plusieurs raisons pour lesquelles un processus Node.js peut se terminer. Certains d'entre eux sont évitables, par exemple lorsqu'une erreur est générée, tandis que d'autres sont inévitables, comme le manque de mémoire. Le process
global est une instance Event Emitter qui émet un événement exit
lorsque l'exécution se termine normalement. Le code du programme peut ensuite effectuer le travail de nettoyage final de la synchronisation en écoutant cet événement.
Recommandations associées : "Tutoriel Nodejs"
Voici quelques façons de déclencher activement l'arrêt du processus :
操作 | 例子 |
---|---|
手动流程退出 | process.exit(1) |
未捕获的异常 | throw new Error() |
未兑现的 promise | Promise.reject() |
忽略的错误事件 | EventEmitter#emit('error') |
未处理的信号 | $ kill <PROCESS_ID> |
Beaucoup d'entre eux sont déclenchés accidentellement, comme des erreurs non détectées ou des promesses non gérées, mais certains sont créés pour terminer directement le processus.
Utiliser process.exit(code)
pour terminer le processus est le moyen le plus direct. Ceci est utile lorsque vous savez que votre processus a atteint la fin de son cycle de vie. La valeur code
est facultative, avec une valeur par défaut de 0 et une valeur maximale de 255. 0 indique que le processus s'est exécuté avec succès, tandis que tout nombre différent de zéro indique qu'un problème est survenu. Ces valeurs peuvent être utilisées par de nombreux outils externes différents. Par exemple, lorsqu'une suite de tests est exécutée, une valeur non nulle indique que le test a échoué.
Lors de l'appel direct de process.exit()
, aucun texte implicite n'est écrit sur la console. Si vous écrivez du code qui appelle cette méthode avec une représentation d'erreur, votre code doit afficher l'erreur à l'utilisateur pour l'aider à résoudre le problème. Par exemple, exécutez le code suivant :
$ node -e "process.exit(42)" $ echo $?
Dans ce cas, le programme Node.js sur une seule ligne ne produira aucune information, bien que le programme shell imprime l'état de sortie. Lorsqu'il rencontre une telle sortie de processus, l'utilisateur ne pourra pas comprendre ce qui s'est passé. Veuillez donc vous référer au code suivant qui sera exécuté lorsque le programme est mal configuré :
function checkConfig(config) { if (!config.host) { console.error("Configuration is missing 'host' parameter!"); process.exit(1); } }
Dans ce cas, l'utilisateur ne saura pas ce qui se passe. Ils exécutent le programme, il affiche les erreurs sur la console et sont capables de corriger le problème.
process.exit()
La méthode est très puissante. Bien qu’il ait ses propres utilisations dans le code d’un programme, il ne doit jamais être introduit dans une bibliothèque réutilisable. Si une erreur se produit dans la bibliothèque, cette erreur doit être générée afin que le programme puisse décider comment la gérer.
Bien que process.exit()
soit utile, pour les erreurs d'exécution, vous devrez utiliser d'autres outils. Par exemple, lorsqu'un programme traite une requête HTTP, une erreur ne doit généralement pas mettre fin au processus, mais uniquement renvoyer une réponse d'erreur. Il est également utile de savoir où l'erreur s'est produite, c'est-à-dire où l'objet Error
doit être lancé. Les instances de la classe
Error
contiennent des métadonnées utiles sur la cause de l'erreur, telles que des informations de trace de pile et des chaînes de message. Il est courant d'étendre votre propre classe d'erreur à partir de Error
. L'instanciation de Error
seule n'aura pas beaucoup d'effets secondaires et devra être lancée si une erreur se produit.
sera déclenché lorsque le mot-clé throw
est utilisé ou lorsqu'une erreur logique se produit. Lorsque cela se produit, la pile actuelle sera « déroulée », ce qui signifie que chaque fonction se terminera jusqu'à ce qu'une fonction appelante enveloppe l'appel dans une instruction Error
. Après avoir rencontré cette déclaration, la succursale try/catch
sera appelée. Si l'erreur n'est pas entourée de catch
, l'erreur est considérée comme non détectée. try/catch
avec Error
comme throw
, techniquement, vous pouvez lancer n'importe quoi. Une fois que quelque chose est lancé, cela est considéré comme une exception. Il est important de lancer des instances throw new Error('foo')
car le code qui détecte ces erreurs s'attendra très probablement à un attribut d'erreur. Error
Un autre modèle couramment utilisé dans les bibliothèques internes de Node.j consiste à fournir un attribut qui est une valeur de chaîne qui doit être cohérente entre les versions. Par exemple, la mauvaise valeur .code
est .code
Même si l'attribut ERR_INVALID_URI
lisible par l'homme peut changer, cette valeur .message
ne doit pas être modifiée. code
, qui est généralement dynamique car des fautes d'orthographe peuvent devoir être corrigées. Cette méthode est très risquée et sujette aux erreurs. Il n'existe pas de solution parfaite dans l'écosystème Node.js pour distinguer les bugs dans toutes les bibliothèques. .message
/tmp/foo.js:1 throw new TypeError('invalid foo'); ^ Error: invalid foo at Object.<anonymous> (/tmp/foo.js:2:11) ... TRUNCATED ... at internal/main/run_main_module.js:17:47
. foo.js
global est un émetteur d'événements qui peut intercepter les erreurs non détectées en écoutant les événements process
. Voici un exemple d'utilisation, en interceptant les erreurs avant de quitter pour envoyer un message asynchrone : uncaughtException
const logger = require('./lib/logger.js'); process.on('uncaughtException', (error) => { logger.send("An uncaught exception has occured", error, () => { console.error(error); process.exit(1); }); });
de la promesse est appelée ou si une erreur est générée dans la fonction asynchrone. À cet égard, les deux exemples suivants sont à peu près les mêmes : reject()
Promise.reject(new Error('oh no')); (async () => { throw new Error('oh no'); })();
(node:52298) UnhandledPromiseRejectionWarning: Error: oh no at Object.<anonymous> (/tmp/reject.js:1:16) ... TRUNCATED ... at internal/main/run_main_module.js:17:47 (node:52298) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch().
: process
process.on('unhandledRejection', (reason, promise) => {});
事件发射器是 Node.js 中的常见模式,许多对象实例都从这个基类扩展而来,并在库和程序中使用。它们非常欢迎,值得和 error 与 rejection 放在一起讨论。
当事件发射器发出没有侦听器的 error
事件时,将会抛出所发出的参数。然后将抛出出一个错误并导致进程退出:
events.js:306 throw err; // Unhandled 'error' event ^ Error [ERR_UNHANDLED_ERROR]: Unhandled error. (undefined) at EventEmitter.emit (events.js:304:17) at Object.<anonymous> (/tmp/foo.js:1:40) ... TRUNCATED ... at internal/main/run_main_module.js:17:47 { code: 'ERR_UNHANDLED_ERROR', context: undefined }
确保在你使用的事件发射器实例中侦听 error
事件,以便你的程序可以正常处理事件而不会崩溃。
信号是操作系统提供的机制,用于把用数字表示的消息从一个程序发送到另一个程序。这些数字通常用等价的常量字符串来表示。例如,信号 SIGKILL
代表数字信号 9。信号可以有不同的用途,但通常用于终止程序。
不同的操作系统可以定义不同的信号,但是下面列表中的信号一般是通用的:
名称 | 编号 | 可处理 | Node.js 默认 | 信号用途 |
---|---|---|---|---|
SIGHUP | 1 | 是 | 终止 | 父终端已关闭 |
SIGINT | 2 | 是 | 终止 | 终端试图中断,按下 Ctrl + C |
SIGQUIT | 3 | 是 | 终止 | 终端试图退出,按下 Ctrl + D |
SIGKILL | 9 | 否 | 终止 | 进程被强行杀死 |
SIGUSR1 | 10 | 是 | 启动调试器 | 用户定义的信号1 |
SIGUSR2 | 12 | 是 | 终止 | 用户定义的信号2 |
SIGTERM | 12 | 是 | 终止 | 代表优雅的终止 |
SIGSTOP | 19 | 否 | 终止 | 进程被强行停止 |
如果程序可以选择实现信号处理程序,则 Handleable 一列则为是。为否的两个信号无法处理。 Node.js 默认 这一列告诉你在收到信号时,Node.js 程序的默认操作是什么。最后一个信号用途指出了信号对应的作用。
在 Node.js 程序中处理这些信号可以通过侦听 process
对象上的更多事件来完成:
#!/usr/bin/env node console.log(`Process ID: ${process.pid}`); process.on('SIGHUP', () => console.log('Received: SIGHUP')); process.on('SIGINT', () => console.log('Received: SIGINT')); setTimeout(() => {}, 5 * 60 * 1000); // keep process alive
在终端窗口中运行这个程序,然后按 Ctrl + C
,这个进程不会被终止。它将会声明已接收到 SIGINT
信号。切换到另一个终端窗口,并根据输出的进程 ID 值执行以下命令:
$ kill -s SIGHUP <PROCESS_ID>
这演示了一个程序怎样向另一个程序发送信号,并且在第一个终端中运行的 Node.js 程序中输出它所接收到的 SIGHUP
信号。
你可能已经猜到了,Node.js 也能把命令发送到其他程序。可以用下面的命令以把信号从临时的 Node.js 进程发送到你现有的进程:
$ node -e "process.kill(<PROCESS_ID>, 'SIGHUP')"
这还会在你的第一个程序中显示 SIGHUP
消息。现在,如果你想终止第一个进程,要运行下面的命令向其发送不能处理的 SIGKILL
信号:
$ kill -9 <PROCESS_ID>
这时程序应该结束。
这些信号在 Node.js 程序中经常用于处理正常的关闭事件。例如,当 Kubernetes Pod 终止时,它将向程序发送 SIGTERM
信号,之后启动 30 秒计时器。然后程序可以在这 30 秒内正常关闭自己,关闭连接并保存数据。如果该进程在此计时器后仍保持活动状态,则 Kubernetes 将向其发送一个 SIGKILL
。
更多编程相关知识,请访问:编程视频!!
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!