解析Node.js異常處理中domain模組的使用方法_node.js
NodeJS 提供了 domain 模組,可以簡化非同步程式碼的異常處理。在介紹這個模組之前,我們需要先理解「域」的概念。簡單的講,一個域就是一個 JS 運行環境,在一個運行環境中,如果一個異常沒有被捕獲,將作為一個全域異常被拋出。 NodeJS 透過 process 物件提供了捕捉全域異常的方法,範例程式碼如下
process.on('uncaughtException', function (err) { console.log('Error: %s', err.message); }); setTimeout(function (fn) { fn(); });
Error: undefined is not a function
雖然全域異常有個地方可以捕獲了,但是對於大多數異常,我們希望儘早捕獲,並根據結果決定程式碼的執行路徑。我們用以下 HTTP 伺服器程式碼作為範例:
function async(request, callback) { // Do something. asyncA(request, function (err, data) { if (err) { callback(err); } else { // Do something asyncB(request, function (err, data) { if (err) { callback(err); } else { // Do something asyncC(request, function (err, data) { if (err) { callback(err); } else { // Do something callback(null, data); } }); } }); } }); } http.createServer(function (request, response) { async(request, function (err, data) { if (err) { response.writeHead(500); response.end(); } else { response.writeHead(200); response.end(data); } }); });
以上程式碼將請求物件交給非同步函數處理後,再根據處理結果回傳回應。這裡採用了使用回呼函數傳遞異常的方案,因此 async 函數內部如果再多幾個非同步函數呼叫的話,程式碼就變成上邊這副鬼樣子了。為了讓程式碼好好看點,我們可以在每處理一個請求時,使用 domain 模組建立一個子域(JS 子運行環境)。在子域內運行的程式碼可以隨意拋出異常,而這些異常可以透過子域物件的 error 事件統一捕獲。於是以上程式碼可以做以下改造:
function async(request, callback) { // Do something. asyncA(request, function (data) { // Do something asyncB(request, function (data) { // Do something asyncC(request, function (data) { // Do something callback(data); }); }); }); } http.createServer(function (request, response) { var d = domain.create(); d.on('error', function () { response.writeHead(500); response.end(); }); d.run(function () { async(request, function (data) { response.writeHead(200); response.end(data); }); }); });
可以看到,我們使用.create方法建立了一個子域對象,並透過.run方法進入需要在子域中運行的程式碼的入口點。而位於子域中的非同步函數回呼函數由於不再需要捕獲異常,程式碼一下子瘦身很多。
陷阱
無論是透過process 物件的uncaughtException 事件擷取到全域異常,還是透過子網域物件的error 事件擷取到了子網域異常,在NodeJS 官方文件裡都強烈建議處理完異常後立即重啟程序,而不是讓程式繼續運行。根據官方文件的說法,發生異常後的程式處於不確定的運行狀態,如果不立即退出的話,程式可能會發生嚴重記憶體洩漏,也可能表現得很奇怪。
但這裡需要澄清一些事實。 JS 本身的throw..try..catch異常處理機制並不會導致記憶體洩漏,也不會讓程式的執行結果出乎意料,但 NodeJS 並不是存粹的 JS。 NodeJS 裡大量的API 內部是用C/C++ 實現的,因此NodeJS 程式的運行過程中,程式碼執行路徑穿梭於JS 引擎內部和外部,而JS 的異常拋出機制可能會打斷正常的程式碼執行流程,導致C/C++ 部分的程式碼表現異常,進而導致記憶體洩漏等問題。
因此,使用 uncaughtException 或 domain 捕獲異常,程式碼執行路徑裡涉及到了 C/C++ 部分的程式碼時,如果無法確定是否會導致記憶體洩漏等問題,最好在處理完異常後重啟程式比較妥當。而使用 try 語句捕捉異常時一般捕獲到的都是 JS 本身的異常,不用擔心上訴問題。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

C++中函數異常處理對於多執行緒環境特別重要,以確保執行緒安全性和資料完整性。透過try-catch語句,可以在出現異常時擷取和處理特定類型的異常,以防止程式崩潰或資料損壞。

PiNetwork節點詳解及安裝指南本文將詳細介紹PiNetwork生態系統中的關鍵角色——Pi節點,並提供安裝和配置的完整步驟。 Pi節點在PiNetwork區塊鏈測試網推出後,成為眾多先鋒積極參與測試的重要環節,為即將到來的主網發布做準備。如果您還不了解PiNetwork,請參考Pi幣是什麼?上市價格多少? Pi用途、挖礦及安全性分析。什麼是PiNetwork? PiNetwork項目始於2019年,擁有其專屬加密貨幣Pi幣。該項目旨在創建一個人人可參與

C++異常處理允許建立自訂錯誤處理例程,透過拋出異常並使用try-catch區塊捕捉異常來處理運行時錯誤。 1.建立一個派生自exception類別的自訂異常類別並覆寫what()方法;2.使用throw關鍵字拋出異常;3.使用try-catch區塊捕捉異常並指定可以處理的異常類型。

遞歸呼叫中的異常處理:限制遞歸深度:防止堆疊溢位。使用異常處理:使用try-catch語句處理異常。尾遞歸優化:避免堆疊溢位。

C++Lambda表達式中的異常處理沒有自己的作用域,預設不捕獲異常。要捕獲異常,可以使用Lambda表達式捕獲語法,它允許Lambda表達式捕獲其定義範圍內的變量,從而在try-catch區塊中進行異常處理。

在多執行緒C++中,例外處理遵循以下原則:及時性、執行緒安全性和明確性。在實戰中,可以透過使用mutex或原子變數來確保異常處理程式碼線程安全。此外,還要考慮異常處理程式碼的重入性、效能和測試,以確保其在多執行緒環境中安全有效地運作。

PHP異常處理:透過異常追蹤了解系統行為異常是PHP用來處理錯誤的機制,由異常處理程序處理異常。異常類別Exception代表一般異常,而Throwable類別代表所有異常。使用throw關鍵字拋出異常,並使用try...catch語句定義異常處理程序。在實戰案例中,透過異常處理捕獲並處理calculate()函數可能拋出的DivisionByZeroError,確保應用程式在發生錯誤時也能優雅地失敗。

在PHP中,異常處理通過try,catch,finally,和throw關鍵字實現。 1)try塊包圍可能拋出異常的代碼;2)catch塊處理異常;3)finally塊確保代碼始終執行;4)throw用於手動拋出異常。這些機制幫助提升代碼的健壯性和可維護性。
