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

Node.js中出現(xiàn)未捕獲異常的處理方法

 更新時間:2020年06月29日 08:33:55   作者:五月君  
這篇文章主要給大家介紹了關(guān)于Node.js中出現(xiàn)未捕獲異常的處理方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面來一起學(xué)習學(xué)習吧

前言

Node.js 程序運行在單進程上,應(yīng)用開發(fā)時一個難免遇到的問題就是異常處理,對于一些未捕獲的異常處理起來,也不是一件容易的事情。

未捕獲異常的程序

下面展示了一段簡單的應(yīng)用程序,如下所示:

const http = require('http');
const PORT = 3000;
const server = http.createServer((req, res) => {
 if (req.url === '/error') {
  a.b;
  res.end('error');
 } else {
  setTimeout(() => res.end('ok!'), 1000 * 10);
 }
});

 
server.listen(PORT, () => console.log(`port is listening on ${PORT}.`));

運行以上程序,在右側(cè)第二個窗口中執(zhí)行了 /error 路由,因為沒有定義 a 這個對象,則會引發(fā)錯誤。

進程崩潰退出之后導(dǎo)致整個應(yīng)用程序也將崩潰,左側(cè)是一個延遲的響應(yīng),也將無法正常工作。

這是一個頭疼的問題,不要緊,下文我們將會學(xué)到一個優(yōu)雅退出的方案。

進程崩潰優(yōu)雅退出

關(guān)于錯誤捕獲,Node.js 官網(wǎng)曾提供了一個模塊 domain 來實現(xiàn),但是現(xiàn)在已廢棄了所以就不再考慮了。

之前在看 CNPM 這個項目時看到了以下關(guān)于錯誤退出的一段代碼:

// https://github.com/cnpm/cnpmjs.org/blob/master/worker.js#L18
graceful({
 server: [registry, web],
 error: function (err, throwErrorCount) {
  if (err.message) {
   err.message += ' (uncaughtException throw ' + throwErrorCount + ' times on pid:' + process.pid + ')';
  }
  console.error(err);
  console.error(err.stack);
  logger.error(err);
 }
});

上述使用的是 graceful 這個模塊,在 NPM 上可以找到。

實現(xiàn)一個 graceful.js

實現(xiàn)一個 graceful 函數(shù),初始化加載時注冊 uncaughtException、unhandledRejection 兩個錯誤事件,分別監(jiān)聽未捕獲的錯誤信息和未捕獲的 Promise 錯誤信息。

const http = require('http');

/**
 * graceful
 * @param { Number } options.killTimeout 超時時間
 * @param { Function } options.onError 產(chǎn)生錯誤信息會執(zhí)行該回調(diào)函數(shù)
 * @param { Array } options.servers Http Server
 * @returns
 */
function graceful(options = {}) {
 options.killTimeout = options.killTimeout || 1000 * 30;
 options.onError = options.onError || function () {};
 options.servers= options.servers || [];
 process.on('uncaughtException', error => handleUncaughtException(error, options));
 process.on('unhandledRejection', error => handleUnhandledRejection(error, options));
}

handleUncaughtException、handleUnhandledRejection 分別接收相應(yīng)的錯誤事件,執(zhí)行應(yīng)用傳入的 onError() 將錯誤信息進行回傳,最后調(diào)用 handleError()。

const throwCount = {
 uncaughtException: 0,
 unhandledRejection: 0
};
function handleUncaughtException(error, options) {
 throwCount.uncaughtException += 1;
 options.onError(error, 'uncaughtException', throwCount.uncaughtException);

 if (throwCount.uncaughtException > 1) return;
 handleError(options);
};

function handleUnhandledRejection(error, options) {
 throwCount.unhandledRejection += 1;
 options.onError(error, 'unhandledRejection', throwCount.unhandledRejection);

 if (throwCount.unhandledRejection > 1) return;
 handleError(options);
}

HandleError 方法為核心實現(xiàn),首先遍歷應(yīng)用傳入的 servers,監(jiān)聽 request 事件,在未捕獲錯誤觸發(fā)之后,如果還有請求鏈接,則關(guān)閉當前請求的鏈接。

之后,執(zhí)行 setTimeout 延遲退出,也就是最大可能的等待之前鏈接處理完成。

function handleError(options) {
 const { servers, killTimeout } = options;
 // 關(guān)閉當前請求的鏈接
 for (const server of servers) {
  console.log('server instanceof http.Server: ', server instanceof http.Server);
  if (server instanceof http.Server) {
   server.on('request', (req, res) => {
    req.shouldKeepAlive = false;
    res.shouldKeepAlive = false;
    if (!res._header) {
     res.setHeader('Connection', 'close');
    }
   });
  }
 }

 // 延遲退出
 const timer = setTimeout(() => {
  process.exit(1);
 }, killTimeout);
 
 if (timer && timer.unref) {
  timer.unref();
 }
}
module.exports = graceful;

應(yīng)用程序中使用上述實現(xiàn)

加載上述 graceful.js 使用起來很簡單只需要在文件尾部,加載 graceful 函數(shù)并傳入相應(yīng)參數(shù)即可。

const graceful = require('./graceful.js');
...
server.listen(PORT, () => console.log(`port is listening on ${PORT}.`));

graceful({
 servers: [server],
 onError: (error, type, throwErrorCount) => {
  console.log('[%s] [pid: %s] [throwErrorCount: %s] %s: %s', new Date(), process.pid, throwErrorCount, type, error.stack || error);
 }
});

再次運行應(yīng)用程序,看看效果:

這一次,即使右側(cè) /error 路由產(chǎn)生未捕獲異常,也將不會引起左側(cè)請求無法正常響應(yīng)。

Graceful 模塊

最后推薦一個 NPM 模塊 graceful,引用文檔中的一句話:“It's the best way to handle uncaughtException on current situations.”

該模塊還提供了對于 Node.js 中 Cluster 模塊的支持。

安裝

$ npm install graceful -S

應(yīng)用

如果一個進程中有多個 Server,將它們添加到 servers 中即可。

const graceful = require('graceful');
...

graceful({
 servers: [server1, server2, restapi],
 killTimeout: '15s',
});

總結(jié)

如果你正在使用 Node.js 對于異常你需要有些了解,上述講解的兩個異常事件可以做為你的最后補救措施,但是不應(yīng)該當作 On Error Resume Next(出了錯誤就恢復(fù)讓它繼續(xù))的等價機制。

到此這篇關(guān)于Node.js中出現(xiàn)未捕獲異常處理方法的文章就介紹到這了,更多相關(guān)Node.js未捕獲異常內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

Reference

  • nodejs.cn/api/process.html
  • www.npmjs.com/package/graceful

相關(guān)文章

  • 深入理解Node.js中通用基礎(chǔ)設(shè)計模式

    深入理解Node.js中通用基礎(chǔ)設(shè)計模式

    大家在談到設(shè)計模式時最先想到的就是 singletons, observers(觀察者) 或 factories(工廠方法)。本文重點給大家介紹Node.JS一些基礎(chǔ)模式的實現(xiàn)方法,感興趣的朋友跟隨腳本之家小編一起學(xué)習吧
    2017-09-09
  • Node.js DES加密的簡單實現(xiàn)

    Node.js DES加密的簡單實現(xiàn)

    下面小編就為大家?guī)硪黄狽ode.js DES加密的簡單實現(xiàn)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-07-07
  • nodejs關(guān)于中間件解析

    nodejs關(guān)于中間件解析

    這篇文章主要介紹了nodejs關(guān)于中間件解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • 解決下載了nodejs但npm?-v沒有反應(yīng)問題的全過程

    解決下載了nodejs但npm?-v沒有反應(yīng)問題的全過程

    最近工作中遇到了個問題,node安裝成功,但npm無法使用,所以下面這篇文章主要給大家介紹了關(guān)于下載了nodejs但npm?-v沒有反應(yīng)問題解決的相關(guān)資料,需要的朋友可以參考下
    2022-08-08
  • Node.js中,在cmd界面,進入退出Node.js運行環(huán)境的方法

    Node.js中,在cmd界面,進入退出Node.js運行環(huán)境的方法

    今天小編就為大家分享一篇Node.js中,在cmd界面,進入退出Node.js運行環(huán)境的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • node.js去水印方法實例分析

    node.js去水印方法實例分析

    這篇文章主要介紹了node.js去水印方法,結(jié)合實例形式分析了node.js基于第三方平臺實現(xiàn)去水印的相關(guān)交互與操作技巧,需要的朋友可以參考下
    2023-04-04
  • 詳解如何優(yōu)雅在webpack項目實現(xiàn)mock服務(wù)器

    詳解如何優(yōu)雅在webpack項目實現(xiàn)mock服務(wù)器

    這篇文章主要為大家介紹了詳解如何優(yōu)雅在webpack項目實現(xiàn)mock服務(wù)器,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • node中modules.exports與exports導(dǎo)出的區(qū)別

    node中modules.exports與exports導(dǎo)出的區(qū)別

    這篇文章主要介紹了node中modules.exports與exports導(dǎo)出的區(qū)別,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06
  • 詳解Node.js如何處理ES6模塊

    詳解Node.js如何處理ES6模塊

    學(xué)習JavaScript語言,你會發(fā)現(xiàn)它有兩種格式的模塊。一種是ES6模塊,簡稱ESM;另一種是Node.js專用的CommonJS模塊,簡稱 CJS。這兩種模塊不兼容。很多人使用Node.js,只會用require()加載模塊,遇到ES6模塊就不知道該怎么辦。本文就來談?wù)凟S6模塊在Node.js里面怎么使用。
    2021-05-05
  • Nodejs實現(xiàn)多人同時在線移動鼠標的小游戲分享

    Nodejs實現(xiàn)多人同時在線移動鼠標的小游戲分享

    這篇文章主要介紹了Nodejs實現(xiàn)多人同時在線移動鼠標的小游戲分享,本文給出了服務(wù)器端和客戶端代碼以及運行方法,需要的朋友可以參考下
    2014-12-12

最新評論

大洼县| 龙南县| 甘孜县| 惠水县| 铁岭县| 青田县| 沾化县| 永定县| 上犹县| 河北省| 长春市| 江城| 临潭县| 奈曼旗| 南丹县| 汝州市| 冷水江市| 丹阳市| 南汇区| 清远市| 金坛市| 兴安县| 敦化市| 静海县| 南城县| 乌兰浩特市| 昌平区| 广丰县| 潜山县| 綦江县| 双辽市| 双城市| 濮阳市| 宜宾市| 华坪县| 彩票| 汾阳市| 昌平区| 靖远县| 高邮市| 静乐县|