欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

前言

Node.js 程序運(yùn)行在單進(jìn)程上,應(yīng)用開(kāi)發(fā)時(shí)一個(gè)難免遇到的問(wèn)題就是異常處理,對(duì)于一些未捕獲的異常處理起來(lái),也不是一件容易的事情。

未捕獲異常的程序

下面展示了一段簡(jiǎn)單的應(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}.`));

運(yùn)行以上程序,在右側(cè)第二個(gè)窗口中執(zhí)行了 /error 路由,因?yàn)闆](méi)有定義 a 這個(gè)對(duì)象,則會(huì)引發(fā)錯(cuò)誤。

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

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

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

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

之前在看 CNPM 這個(gè)項(xiàng)目時(shí)看到了以下關(guān)于錯(cuò)誤退出的一段代碼:

// 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 這個(gè)模塊,在 NPM 上可以找到。

實(shí)現(xiàn)一個(gè) graceful.js

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

const http = require('http');

/**
 * graceful
 * @param { Number } options.killTimeout 超時(shí)時(shí)間
 * @param { Function } options.onError 產(chǎn)生錯(cuò)誤信息會(huì)執(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)的錯(cuò)誤事件,執(zhí)行應(yīng)用傳入的 onError() 將錯(cuò)誤信息進(jìn)行回傳,最后調(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 方法為核心實(shí)現(xiàn),首先遍歷應(yīng)用傳入的 servers,監(jiān)聽(tīng) request 事件,在未捕獲錯(cuò)誤觸發(fā)之后,如果還有請(qǐng)求鏈接,則關(guān)閉當(dāng)前請(qǐng)求的鏈接。

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

function handleError(options) {
 const { servers, killTimeout } = options;
 // 關(guān)閉當(dāng)前請(qǐng)求的鏈接
 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)用程序中使用上述實(shí)現(xiàn)

加載上述 graceful.js 使用起來(lái)很簡(jiǎn)單只需要在文件尾部,加載 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ùn)行應(yīng)用程序,看看效果:

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

Graceful 模塊

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

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

安裝

$ npm install graceful -S

應(yīng)用

如果一個(gè)進(jìn)程中有多個(gè) Server,將它們添加到 servers 中即可。

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

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

總結(jié)

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

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

Reference

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

相關(guān)文章

  • node后端服務(wù)?;畹膶?shí)現(xiàn)

    node后端服務(wù)?;畹膶?shí)現(xiàn)

    這篇文章主要介紹了node后端服務(wù)保活的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • node版本太高導(dǎo)致項(xiàng)目跑不起來(lái)的解決辦法(windows)

    node版本太高導(dǎo)致項(xiàng)目跑不起來(lái)的解決辦法(windows)

    換了臺(tái)電腦后,安裝node,一切完美,發(fā)現(xiàn)其中有一個(gè)uniapp的小程序項(xiàng)目跑不起來(lái),感覺(jué)是node版本太高導(dǎo)致的,所以只能重新安裝低版本的node,本文給大家介紹了node版本太高的解決辦法,需要的朋友可以參考下
    2023-10-10
  • Node.js?子線程Crash?問(wèn)題的排查方法

    Node.js?子線程Crash?問(wèn)題的排查方法

    這篇文章主要介紹了Node.js?子線程Crash?問(wèn)題的排查,本文通過(guò)代碼例子給大家詳細(xì)講解,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • Node.js 的異步 IO 性能探討

    Node.js 的異步 IO 性能探討

    Node.js 的賣點(diǎn)是「異步單線程」,雖然主流 Web 后端編程語(yǔ)言中,對(duì)異步編程有很好支持的語(yǔ)言并不少,但只有 Node.js 喪心病狂地將所有 IO 強(qiáng)制異步進(jìn)行。
    2014-10-10
  • win系統(tǒng)下nodejs環(huán)境安裝配置

    win系統(tǒng)下nodejs環(huán)境安裝配置

    這篇文章主要介紹了win系統(tǒng)下nodejs環(huán)境安裝配置的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • Node.js打包管理工具NPM用法

    Node.js打包管理工具NPM用法

    這篇文章介紹了Node.js打包管理工具NPM的用法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • 基于Nodejs實(shí)現(xiàn)文件壓縮和解壓功能

    基于Nodejs實(shí)現(xiàn)文件壓縮和解壓功能

    在?windows?系統(tǒng)上面,我們壓縮文件,常常需要安裝一些壓縮軟件才能實(shí)現(xiàn)壓縮,可能有些還存在一些問(wèn)題,所以本文就來(lái)使用Nodejs實(shí)現(xiàn)文件壓縮和解壓功能吧
    2024-03-03
  • 如何刪除所有node_modules和package-lock配置文件

    如何刪除所有node_modules和package-lock配置文件

    這篇文章主要介紹了如何刪除所有node_modules和package-lock配置文件問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • Node 創(chuàng)建第一個(gè)服務(wù)器應(yīng)用的操作方法

    Node 創(chuàng)建第一個(gè)服務(wù)器應(yīng)用的操作方法

    Node.js是一個(gè)基于Chrome V8引擎的JavaScript運(yùn)行環(huán)境,可以用于構(gòu)建高性能的網(wǎng)絡(luò)應(yīng)用程序,它采用事件驅(qū)動(dòng)、非阻塞I/O模型,使得程序可以以高效地方式處理并發(fā)請(qǐng)求,這篇文章主要介紹了Node 創(chuàng)建第一個(gè)服務(wù)器應(yīng)用,需要的朋友可以參考下
    2024-02-02
  • node.js解決獲取圖片真實(shí)文件類型的問(wèn)題

    node.js解決獲取圖片真實(shí)文件類型的問(wèn)題

    這篇文章主要介紹了node.js解決獲取圖片真實(shí)文件類型的問(wèn)題,本文根據(jù)二進(jìn)制流及文件頭獲取文件類型mime-type,然后讀取文件二進(jìn)制的頭信息,獲取其真實(shí)的文件類型,需要的朋友可以參考下
    2014-12-12

最新評(píng)論