最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳細(xì)談?wù)凬odeJS進(jìn)程是如何退出的

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

前言

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

下面的表格列舉了可以導(dǎo)致進(jìn)程退出的因素。

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

主動(dòng)退出

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

當(dāng) process.exit() 被使用時(shí),控制臺(tái)不會(huì)有任何輸出,如果我們想在進(jìn)程推出的時(shí)候像控制臺(tái)輸出一些錯(cuò)誤說明信息,則需要在調(diào)用之前顯示的輸出錯(cuò)誤信息。

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

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

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

在上面的代碼中,我們?cè)谶M(jìn)程退出之前輸出的明確的錯(cuò)誤信息。

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

Exceptions, Rejections 和 Emitted Errors

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

比如當(dāng)應(yīng)用在處理一個(gè) HTTP 請(qǐng)求時(shí),一個(gè)錯(cuò)誤不應(yīng)該導(dǎo)致進(jìn)程終止,相反,我們應(yīng)該返回一個(gè)含有錯(cuò)誤信息的響應(yīng)。

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

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

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

當(dāng)一個(gè)未捕獲的異常拋出時(shí),控制臺(tái)會(huì)打印調(diào)用堆棧,同時(shí)進(jìn)程退出,退出狀態(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

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

全局變量 process 是個(gè) Event Emitter 實(shí)例,可以通過監(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 與拋出異常類似。我們可以通過調(diào)用 reject() 函數(shù)或者在 async 函數(shù)中拋出異常來是的 promise 到達(dá) rejected 狀態(tài)。下面的兩段代碼功能是相似的。

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

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

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

下面是一段未捕獲的 Promise Rejection 的控制臺(tái)輸出樣例。

(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 中的基礎(chǔ)模塊,應(yīng)用廣泛。當(dāng) Event Emitter 的 error 事件未被處理時(shí),Event Emitter 就會(huì)拋出一個(gè)錯(cuò)誤,同時(shí)會(huì)導(dǎo)致進(jìn)程退出。下面是一個(gè) Event Emitter error 的控制臺(tái)輸出。

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
}

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

信號(hào)

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

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

這表格里,是否可處理表示這個(gè)信號(hào)是否可被進(jìn)程接收并被處理。NodeJS 默認(rèn)行為表示進(jìn)程在接收到這個(gè)信號(hào)以后默認(rèn)執(zhí)行的動(dòng)作。

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

#!/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

在一個(gè)命令行窗口中運(yùn)行這段代碼,然后按下 Ctrl + C,此時(shí)進(jìn)程不會(huì)退出,而是會(huì)在控制臺(tái)打印一行接收到了 SIGINT 信號(hào)的日志信息。新起一個(gè)命令行窗口,執(zhí)行如下命令,PROCESS_ID 為上面程序輸出的進(jìn)程 ID。

kill -s SIGHUP <PROCESS_ID>

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

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

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

這段代碼同樣會(huì)在第一個(gè)命令行窗口中輸出一行接收到了 SIGHUP 信號(hào)的日志。

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

kill -9 <PROCESS_ID>

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

小結(jié)

本文講述了可以導(dǎo)致進(jìn)程退出的幾種因素,分別是:

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

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

您可能感興趣的文章:

相關(guān)文章

  • 基于NodeJS的前后端分離的思考與實(shí)踐(五)多終端適配

    基于NodeJS的前后端分離的思考與實(shí)踐(五)多終端適配

    對(duì)比基于瀏覽器的響應(yīng)式設(shè)計(jì)方案,因?yàn)榻^大部分終端探測和渲染邏輯遷移到了服務(wù)端,所以在 NodeJS 層進(jìn)行適配無疑帶來了更好的性能和用戶體驗(yàn);另外,相對(duì)于一些所謂的「云適配」方案帶來的轉(zhuǎn)換質(zhì)量問題,在基于前后端分離的「定制式」方案中也不會(huì)存在。
    2014-09-09
  • NodeJS讀取分析Nginx錯(cuò)誤日志的方法

    NodeJS讀取分析Nginx錯(cuò)誤日志的方法

    這篇文章主要介紹了NodeJS讀取分析Nginx錯(cuò)誤日志的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-05-05
  • Express+Nodejs 下的登錄攔截實(shí)現(xiàn)代碼

    Express+Nodejs 下的登錄攔截實(shí)現(xiàn)代碼

    本篇文章主要介紹了Express+Nodejs 下的登錄攔截實(shí)現(xiàn)代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-07-07
  • Node.js+Express+MySql實(shí)現(xiàn)用戶登錄注冊(cè)功能

    Node.js+Express+MySql實(shí)現(xiàn)用戶登錄注冊(cè)功能

    這篇文章主要為大家詳細(xì)介紹了Node.js+Express+MySql實(shí)現(xiàn)用戶登錄注冊(cè),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • ajax +NodeJS 實(shí)現(xiàn)圖片上傳實(shí)例

    ajax +NodeJS 實(shí)現(xiàn)圖片上傳實(shí)例

    本篇文章主要介紹了ajax +NodeJS 實(shí)現(xiàn)圖片上傳實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • nodejs中express入門和基礎(chǔ)知識(shí)點(diǎn)學(xué)習(xí)

    nodejs中express入門和基礎(chǔ)知識(shí)點(diǎn)學(xué)習(xí)

    這篇文章給大家分享了關(guān)于學(xué)習(xí)nodejs中express入門和基礎(chǔ)知識(shí)點(diǎn)內(nèi)容,有興趣的朋友們參考下。
    2018-09-09
  • 詳解nodejs模板引擎制作

    詳解nodejs模板引擎制作

    本篇文章主要介紹了nodejs模板引擎制作 ,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-06-06
  • Node.js版本升級(jí)如何修改模塊默認(rèn)的保存位置

    Node.js版本升級(jí)如何修改模塊默認(rèn)的保存位置

    這篇文章主要給大家介紹了關(guān)于Node.js版本升級(jí)如何修改模塊默認(rèn)的保存位置,文中通過代碼以及圖文介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用node.js具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2024-05-05
  • Node.js安裝詳細(xì)步驟教程(Windows版)詳解

    Node.js安裝詳細(xì)步驟教程(Windows版)詳解

    這篇文章主要介紹了Node.js安裝詳細(xì)步驟教程(Windows版),本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-09-09
  • express的中間件bodyParser詳解

    express的中間件bodyParser詳解

    這篇文章主要介紹了node.js中express的中間件bodyParser的使用方法,需要的朋友可以參考下
    2014-12-12

最新評(píng)論

北票市| 崇明县| 上栗县| 和田市| 盐边县| 康定县| 蒲江县| 临潭县| 陇西县| 桐庐县| 靖江市| 大名县| 朔州市| 磴口县| 庆安县| 平阴县| 云梦县| 枣阳市| 北碚区| 双江| 章丘市| 新田县| 乌苏市| 云和县| 嵩明县| 南昌市| 句容市| 三亚市| 永顺县| 肥乡县| 柳州市| 钦州市| 宁蒗| 本溪| 郓城县| 敦化市| 吉隆县| 鱼台县| 蒙山县| 九寨沟县| 临清市|