首頁 web前端 js教程 解析Node.js異常處理中domain模組的使用方法_node.js

解析Node.js異常處理中domain模組的使用方法_node.js

May 16, 2016 pm 03:15 PM
javascript node 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 本身的異常,不用擔心上訴問題。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

C++ 函式異常與多執行緒:並發環境下的錯誤處理 C++ 函式異常與多執行緒:並發環境下的錯誤處理 May 04, 2024 pm 04:42 PM

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

Pi Node教學:什麼是Pi節點?如何安裝和設定Pi Node? Pi Node教學:什麼是Pi節點?如何安裝和設定Pi Node? Mar 05, 2025 pm 05:57 PM

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

C++ 異常處理如何支援自訂錯誤處理例程? C++ 異常處理如何支援自訂錯誤處理例程? Jun 05, 2024 pm 12:13 PM

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

Java函數中遞歸呼叫與異常處理有何關係? Java函數中遞歸呼叫與異常處理有何關係? May 03, 2024 pm 06:12 PM

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

C++ Lambda 表達式如何進行異常處理? C++ Lambda 表達式如何進行異常處理? Jun 03, 2024 pm 03:01 PM

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

C++ 技術中的例外處理:如何在多執行緒環境中正確處理例外狀況? C++ 技術中的例外處理:如何在多執行緒環境中正確處理例外狀況? May 09, 2024 pm 12:36 PM

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

PHP異常處理:透過異常追蹤了解系統行為 PHP異常處理:透過異常追蹤了解系統行為 Jun 05, 2024 pm 07:57 PM

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

您如何在PHP中有效處理異常(嘗試,捕捉,最後,投擲)? 您如何在PHP中有效處理異常(嘗試,捕捉,最後,投擲)? Apr 05, 2025 am 12:03 AM

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

See all articles