Maison > interface Web > js tutoriel > Explication détaillée de plusieurs méthodes pour terminer activement le processus Node.js

Explication détaillée de plusieurs méthodes pour terminer activement le processus Node.js

青灯夜游
Libérer: 2021-04-27 09:14:31
avant
5994 Les gens l'ont consulté

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.

Explication détaillée de plusieurs méthodes pour terminer activement le processus Node.js

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.

Sortie du 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 $?
Copier après la connexion

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 &#39;host&#39; parameter!");
    process.exit(1);
  }
}
Copier après la connexion

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.

exception, rejet et erreur émise

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

Bien que vous deviez utiliser le mot-clé

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(&#39;foo&#39;) 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

Malheureusement, un modèle plus courant pour distinguer les erreurs consiste à vérifier l'attribut

, 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

Lorsqu'une erreur non détectée est générée, une trace de pile sera imprimée dans la console et le processus se terminera avec l'état de sortie 1. Voici un exemple d'une telle exception :

/tmp/foo.js:1
throw new TypeError(&#39;invalid foo&#39;);
^
Error: invalid foo
    at Object.<anonymous> (/tmp/foo.js:2:11)
    ... TRUNCATED ...
    at internal/main/run_main_module.js:17:47
Copier après la connexion

L'extrait de trace de pile ci-dessus indique que l'erreur s'est produite à la ligne 2, colonne 11 du fichier nommé

. foo.js

Le

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(&#39;./lib/logger.js&#39;);
process.on(&#39;uncaughtException&#39;, (error) => {
  logger.send("An uncaught exception has occured", error, () => {
    console.error(error);
    process.exit(1);
  });
});
Copier après la connexion

Le rejet de la promesse est très similaire au lancement d'une erreur. Une promesse peut être rejetée si la méthode

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(&#39;oh no&#39;));

(async () => {
  throw new Error(&#39;oh no&#39;);
})();
Copier après la connexion

Voici le message affiché sur la console :

(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().
Copier après la connexion

Contrairement aux exceptions non interceptées, à partir de Node.js v14, ces rejets seront pas faire planter le processus. Dans une future version de Node.js, cela fera planter le processus actuel. Vous pouvez également intercepter l'événement lorsque ces rejets non gérés se produisent, en écoutant un autre événement sur l'objet

 : process

process.on(&#39;unhandledRejection&#39;, (reason, promise) => {});
Copier après la connexion

事件发射器是 Node.js 中的常见模式,许多对象实例都从这个基类扩展而来,并在库和程序中使用。它们非常欢迎,值得和 error 与 rejection 放在一起讨论。

当事件发射器发出没有侦听器的 error 事件时,将会抛出所发出的参数。然后将抛出出一个错误并导致进程退出:

events.js:306
    throw err; // Unhandled &#39;error&#39; 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: &#39;ERR_UNHANDLED_ERROR&#39;,
  context: undefined
}
Copier après la connexion

确保在你使用的事件发射器实例中侦听 error 事件,以便你的程序可以正常处理事件而不会崩溃。

信号

信号是操作系统提供的机制,用于把用数字表示的消息从一个程序发送到另一个程序。这些数字通常用等价的常量字符串来表示。例如,信号 SIGKILL 代表数字信号 9。信号可以有不同的用途,但通常用于终止程序。

不同的操作系统可以定义不同的信号,但是下面列表中的信号一般是通用的:

名称编号可处理Node.js 默认信号用途
SIGHUP1终止父终端已关闭
SIGINT2终止终端试图中断,按下 Ctrl + C
SIGQUIT3终止终端试图退出,按下 Ctrl + D
SIGKILL9终止进程被强行杀死
SIGUSR110启动调试器用户定义的信号1
SIGUSR212终止用户定义的信号2
SIGTERM12终止代表优雅的终止
SIGSTOP19终止进程被强行停止

如果程序可以选择实现信号处理程序,则 Handleable 一列则为。为的两个信号无法处理。 Node.js 默认 这一列告诉你在收到信号时,Node.js 程序的默认操作是什么。最后一个信号用途指出了信号对应的作用。

在 Node.js 程序中处理这些信号可以通过侦听 process 对象上的更多事件来完成:

#!/usr/bin/env node
console.log(`Process ID: ${process.pid}`);
process.on(&#39;SIGHUP&#39;, () => console.log(&#39;Received: SIGHUP&#39;));
process.on(&#39;SIGINT&#39;, () => console.log(&#39;Received: SIGINT&#39;));
setTimeout(() => {}, 5 * 60 * 1000); // keep process alive
Copier après la connexion

在终端窗口中运行这个程序,然后按 Ctrl + C,这个进程不会被终止。它将会声明已接收到 SIGINT 信号。切换到另一个终端窗口,并根据输出的进程 ID 值执行以下命令:

$ kill -s SIGHUP <PROCESS_ID>
Copier après la connexion

这演示了一个程序怎样向另一个程序发送信号,并且在第一个终端中运行的 Node.js 程序中输出它所接收到的 SIGHUP 信号。

你可能已经猜到了,Node.js 也能把命令发送到其他程序。可以用下面的命令以把信号从临时的 Node.js 进程发送到你现有的进程:

$ node -e "process.kill(<PROCESS_ID>, &#39;SIGHUP&#39;)"
Copier après la connexion

这还会在你的第一个程序中显示 SIGHUP 消息。现在,如果你想终止第一个进程,要运行下面的命令向其发送不能处理的 SIGKILL 信号:

$ kill -9 <PROCESS_ID>
Copier après la connexion

这时程序应该结束。

这些信号在 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!

Étiquettes associées:
source:segmentfault.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal