可維護的 Node.js JavaScript:避免 process.exit()
在過去的幾個月裡,我一直在深入研究 Node.js,並且像往常一樣,我一直在密切關注我遇到的模式和問題。最近在代碼審查中出現的一個有問題的模式是使用 process.exit()
.我最終找到了幾個這樣的例子,我準備說很少有地方可以調用 process.exit()
有道理。
它的作用
當你調用 process.exit()
(並且可以選擇傳入退出代碼),您會導致處理停止。 exit
事件被觸發,這是任何代碼運行的最後機會,並且事件循環停止。此後不久,Node.js 實際上完全停止並返回指定的退出代碼。所以 process.exit()
在此之後阻止 Node.js 執行任何有形的操作,並且應用程序停止。
問題
就其本身而言,使用指定的退出代碼退出的能力並不是一件可怕的事情。許多編程語言都提供了這種能力,並且依賴於它進行各種處理,其中最重要的是構建工具。真正的問題是 process.exit()
可以隨時被應用程序的任何部分調用。沒有什麼能阻止解析器調用它:
exports.parse = function(text) {
if (canParse(text)) {
return doTheParse(text);
} else {
console.error("Can't parse the text.");
process.exit(1);
}
};
因此,如果可以解析文本,則可以,否則將錯誤輸出到控制台和 process.exit(1)
叫做。對於一個低級的解析器來說,這是一個非常大的責任。我敢肯定其他解析器會嫉妒這個解析器會告訴整個消費應用程序關閉。
由於任何模塊都可以調用 process.exit()
,這意味著任何出錯的函數調用都可能決定關閉應用程序。這不是一個好的狀態。應用程序的一個區域應該決定何時以及是否調用 process.exit()
以及退出代碼應該是什麼(通常是應用程序控制器)。實用程序等不應該使用 process.exit()
,這超出了他們的責任範圍。
該怎麼做
任何時候你想使用 process.exit()
,考慮拋出一個錯誤:
exports.parse = function(text) {
if (canParse(text)) {
return doTheParse(text);
} else {
throw new Error("Can't parse the text.");
}
};
拋出錯誤與調用 process.exit()
的效果相似 在該函數中的代碼執行立即停止。但是,調用函數有機會捕獲錯誤並以優雅的方式響應它。如果調用堆棧上沒有乾預,則 uncaughtException
事件在 process
上觸發 .如果沒有事件處理程序,則 Node.js 將觸發 exit
事件並以非零退出代碼退出,就像 process.exit()
時一樣 叫做;如果有事件處理程序,則由您手動調用 process.exit()
指定要使用的退出代碼。
關鍵是拋出錯誤讓應用程序有機會捕獲錯誤並從中恢復,這幾乎是處理模塊代碼時所期望的情況。
結論
在您的整個應用程序中,可能只需要一次調用 process.exit()
,這應該在應用程序控制器中。所有其他代碼,尤其是模塊中的代碼,應該拋出錯誤而不是使用 process.exit()
.這使應用程序有機會從錯誤中恢復並做一些適當的事情,而不是在操作過程中死掉。調用 process.exit()
相當於說“這是一個致命錯誤”。確保嚴重性適合當前情況,如有疑問,只需拋出錯誤即可。