欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳細談談NodeJS進程是如何退出的

 更新時間:2021年07月14日 11:55:16   作者:眾里千尋  
這篇文章主要給大家介紹了關于NodeJS進程是如何退出的相關資料,主要介紹了導致進程退出的三個因素:主動退出;未捕獲的異常、未處理的 promise rejection;未處理的 Event Emitter error 事件 系統(tǒng)信號,需要的朋友可以參考下

前言

有幾種因素可以導致 NodeJS 進程退出。在這些因素中,有些是可預防的,比如代碼拋出了一個異常;有些是不可預防的,比如內存耗盡。process 這個全局變量是一個 Event Emitter 實例,如果進程優(yōu)雅退出,process 會派發(fā)一個 exit 事件。應用代碼可以監(jiān)聽這個事件,來做最后的清理工作。

下面的表格列舉了可以導致進程退出的因素。

操作 舉例
手動退出 process.exit(1)
未捕獲的異常 throw new Error()
未處理的 promise rejection Promise.reject()
未處理的 error 事件 EventEmitter#emit('error')
未處理的信號 kill <PROCESS_ID>

主動退出

process.exit(code) 是最直接的結束進程的方法。code 參數(shù)是可選的,可以為 0 ~ 255 之間任何數(shù)字,默認為 0。0 表示進程執(zhí)行成功,非 0 數(shù)字表示進程執(zhí)行失敗。

當 process.exit() 被使用時,控制臺不會有任何輸出,如果我們想在進程推出的時候像控制臺輸出一些錯誤說明信息,則需要在調用之前顯示的輸出錯誤信息。

node -e "process.exit(42)"
echo $?

上面的代碼直接退出了 NodeJS 進程,命令行沒有任何輸出信息。用戶在遭遇進程退出的時候,無法獲取有效的錯誤信息。

function checkConfig(config) {
  if (!config.host) {
    console.error("Configuration is missing 'host' parameter!");
    process.exit(1);
  }
}

在上面的代碼中,我們在進程退出之前輸出的明確的錯誤信息。

process.exit() 的功能非常強大,但是我們不應該在工具庫中使用。如果在工具庫中遇到的錯誤,我們應該以異常的形式拋出,從而讓應用代碼決定如何處理這個錯誤。

Exceptions, Rejections 和 Emitted Errors

process.exit() 在應用啟動配置檢查等場景中非常有用,但是在處理運行時異常時,它并不適用,我們需要其他的工具。

比如當應用在處理一個 HTTP 請求時,一個錯誤不應該導致進程終止,相反,我們應該返回一個含有錯誤信息的響應。

Error 類可以包含描述錯誤發(fā)生的詳細信息的數(shù)據(jù),比如調用堆棧和錯誤文本。通常我們會定義特定場景的 XXXError,這些 XXXError 都繼承制 Error 類。

當我們使用 throw 關鍵字,或者代碼邏輯出錯時,一個錯誤就會被拋出。此時,系統(tǒng)調用棧會釋放,每個函數(shù)會退出,直到遇到一個 包裹了當前調用的 try/catch 語句。如果沒有 try/catch 語句,則這個錯誤會被認為是未捕獲的異常。

通常,在 NodeJS 應用中,我們會給 Error 類定義一個 code 屬性,作為用來描述具體錯誤的錯誤碼,這么做的優(yōu)點是可以使錯誤碼保持唯一,同時還能使得錯誤碼是可讀的。同時,我們也可以配合 message 屬性來描述具體的錯誤信息。

當一個未捕獲的異常拋出時,控制臺會打印調用堆棧,同時進程退出,退出狀態(tài)碼為 1.

/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

這段控制臺輸出信息說明,錯誤發(fā)生在 foo.js 中的第 2 行第 11 列。

全局變量 process 是個 Event Emitter 實例,可以通過監(jiān)聽 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);
  });
});

Promise Rejection 與拋出異常類似。我們可以通過調用 reject() 函數(shù)或者在 async 函數(shù)中拋出異常來是的 promise 到達 rejected 狀態(tài)。下面的兩段代碼功能是相似的。

Promise.reject(new Error("oh no"));

(async () => {
  throw new Error("oh no");
})();

目前,在 NodeJS 14 中,Promise Rejection 不會導致進程退出,在后續(xù)的版本中,Promise Rejection 可能會導致進程退出。

下面是一段未捕獲的 Promise Rejection 的控制臺輸出樣例。

(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().

我們可以通過監(jiān)聽 unhandledRejection 事件來處理未捕獲的 Rejection. 樣例代碼如下:

process.on("unhandledRejection", (reason, promise) => {});

Event Emitter 是 NodeJS 中的基礎模塊,應用廣泛。當 Event Emitter 的 error 事件未被處理時,Event Emitter 就會拋出一個錯誤,同時會導致進程退出。下面是一個 Event Emitter 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
}

因此,我們在使用 Event Emitter 的時候,要確保監(jiān)聽了 error 事件,這樣在發(fā)生錯誤的時候,可以使得應用能夠處理這些錯誤,避免奔潰。

信號

信號是操作信息提供了進程間通信機制。信號通常是一個數(shù)字,同時也可以使用一個字符串來標識。比如 SIGKILL 標識數(shù)字 9。不同的操作系統(tǒng)對信號的定義不同。下面表格里羅列的是基本通用的信號定義。

名稱 數(shù)字 是否可處理 NodeJS 默認行為 信號的含義
SIGHUP 1 Yes 退出 父命令行被關閉
SIGINT 2 Yes 退出 命令行嘗試中斷,即 Ctrl + C
SIGQUIT 3 Yes 退出 命令行嘗試退出,即 Ctrl + Z
SIGKILL 9 No 退出 強制進程退出
SIGUSR1 10 Yes 啟動調試器 用戶自定義信號
SIGUSR2 12 Yes 退出 用戶自定義信號
SIGTERM 15 Yes 退出 進程優(yōu)雅的退出
SIGSTOP 19 No 退出 進程被強制停止

這表格里,是否可處理表示這個信號是否可被進程接收并被處理。NodeJS 默認行為表示進程在接收到這個信號以后默認執(zhí)行的動作。

我們可以通過如下方式來監(jiān)聽這些信號。

#!/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 信號的日志信息。新起一個命令行窗口,執(zhí)行如下命令,PROCESS_ID 為上面程序輸出的進程 ID。

kill -s SIGHUP <PROCESS_ID>

通過新起的命令行,我們向原來的那個程序進程發(fā)送了一個 SIGHUP 信號,原來的命令行窗口中會打印一行接收到了 SIGHUP 信號的日志信息。

在 NodeJS 代碼中,進程也可以給其他進程發(fā)送信號。比如:

node -e "process.kill(<PROCESS_ID>, 'SIGHUP')"

這段代碼同樣會在第一個命令行窗口中輸出一行接收到了 SIGHUP 信號的日志。

如果我們要讓第一個命令行窗口的進程退出,則可以通過下面的命令來實現(xiàn)。

kill -9 <PROCESS_ID>

在 NodeJS 中,信號通常被用作控制進程優(yōu)雅的退出。比如,在 Kubernetes 中,當一個 pod 要退出時,k8s 會像 pod 內的進程發(fā)送一個 SIGTERM 的信號,同時啟動一個 30 秒的定時器。應用程序有 30 秒的時間來關閉連接、保存數(shù)據(jù)等。如果 30 秒之后進程依然存活,k8s 會再發(fā)送一個 SIGKILL 來強制關閉進程。

小結

本文講述了可以導致進程退出的幾種因素,分別是:

  • 主動退出
  • 未捕獲的異常、未處理的 promise rejection、未處理的 Event Emitter error 事件
  • 系統(tǒng)信號

到此這篇關于NodeJS進程是如何退出的文章就介紹到這了,更多相關NodeJS進程退出內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關文章

  • Webpack 實現(xiàn) Node.js 代碼熱替換

    Webpack 實現(xiàn) Node.js 代碼熱替換

    Webpack有一個很實用的功能叫做熱替換(Hot-replace),尤其是結合React Hot Loader插件,開發(fā)過程中都不需要刷新瀏覽器,任何前端代碼的更改都會實時的在瀏覽器中表現(xiàn)出來。
    2015-10-10
  • express框架實現(xiàn)基于Websocket建立的簡易聊天室

    express框架實現(xiàn)基于Websocket建立的簡易聊天室

    本篇文章主要介紹了express框架實現(xiàn)基于Websocket建立的簡易聊天室,具有一定的參考價值,有興趣的可以了解一下
    2017-08-08
  • 在Node.js中執(zhí)行解壓縮文件操作方法

    在Node.js中執(zhí)行解壓縮文件操作方法

    本文主要介紹了如何在Node.js中進行解壓縮文件操作,本文也提供了壓縮文件的方法,壓縮文件的文件路徑需要對應自己要壓縮的文件夾路徑,通過本文的介紹,可以幫助讀者更好地理解和使用Node.js進行解壓縮文件操作
    2024-10-10
  • nvm管理node版本的詳細圖文教程

    nvm管理node版本的詳細圖文教程

    nvm全英文也叫node.js version management,是一個nodejs的版本管理工具,下面這篇文章主要給大家介紹了關于nvm管理node版本的詳細圖文教程,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2022-12-12
  • node.js中的console.timeEnd方法使用說明

    node.js中的console.timeEnd方法使用說明

    這篇文章主要介紹了node.js中的console.timeEnd方法使用說明,本文介紹了console.timeEnd的方法說明、語法、使用實例和實現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • 切換node版本的實現(xiàn)方式

    切換node版本的實現(xiàn)方式

    由于有些比較老的系統(tǒng),使用的node版本較低,本機裝的node版本又比較高,不想降node版本,那么就需要考慮能不能在系統(tǒng)里管理多個node版本,本文主要介紹了切換node版本,感興趣的可以了解一下
    2024-04-04
  • 整理 node-sass 安裝失敗的原因及解決辦法(小結)

    整理 node-sass 安裝失敗的原因及解決辦法(小結)

    這篇文章主要介紹了整理 node-sass 安裝失敗的原因及解決辦法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-02-02
  • windows 下安裝nodejs 環(huán)境變量設置

    windows 下安裝nodejs 環(huán)境變量設置

    windows 下安裝nodejs 了,也安裝了npm, 但是有時候切不能直接用request(‘ws’)這一類的東西.我覺得是確實環(huán)境變量或其他設置有問題,能否給個完整的設置方案:
    2017-02-02
  • nodejs一個簡單的文件服務器的創(chuàng)建方法

    nodejs一個簡單的文件服務器的創(chuàng)建方法

    這篇文章主要介紹了nodejs一個簡單的文件服務器的創(chuàng)建方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-09-09
  • nodeJs項目在阿里云的簡單部署

    nodeJs項目在阿里云的簡單部署

    這篇文章主要為大家詳細介紹了nodeJs項目在阿里云的簡單部署,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11

最新評論