NodeJS之異常處理


1. 為什么要處理異常?

如果我們不處理異常的話,直接會導致程序奔潰,用戶體驗比較差,因此我們要對異常進行處理,當出現異常的情況下,我們要給用戶一個友好的提示,並且記錄該異常,方便我們排查。

2. 在Node.js中常用的異常處理方式有哪些?

2.1 使用try catch方式來處理異常,如下代碼:

try {
  throw new Error('error');
} catch(e) {
  console.log('異常被捕獲了,我現在還可以繼續執行了');
  console.log(e);
}

然后執行命令行時候,可以看到如下,也會打印后面的 console.log的信息了;如下所示:

但是使用 try catch 無法處理異步代碼塊內出現的異常,比如如下代碼:

try {
  setTimeout(() => {
    throw new Error('error');
  })
} catch(e) {
  console.log('異常被捕獲了,我現在還可以繼續執行了');
  console.log(e);
}

在命令行中打印信息如下:

可以看到,catch里面的console.log(''); 代碼並沒有被執行。說明catch里面的代碼異常並沒有被捕獲到。

2.2 使用event方式來處理異常

const events = require('events');

// 創建一個事件監聽對象
const emitter = new events.EventEmitter();

// 監聽error事件
emitter.addListener('error', (e) => {
  // 處理異常信息
  console.log(11122222); // 能打印 1112222 說明異常捕獲到了
  console.log(e);
});

// 觸發 error事件
emitter.emit('error', new Error('你代碼出錯了'));

執行效果如下圖所示:

2.3 callback的方式

比如讀取一個文件,或者創建一個目錄,測試代碼如下:

const fs = require('fs');

fs.mkdir('/dir', (e) => {
  if (e) {
    console.log('異常信息處理');
    console.log(e);
  } else {
    console.log('創建目錄成功');
  }
});

然后執行結果如下圖所示:

2.4 Promise方式

new Promise((resolve, reject) => {
  throw new Error('error');
}).then(() => {
  // 。。。。
}).catch((e) => {
  console.log('能進來說明可以處理異常信息了');
  console.log(e);
});

執行結果如下圖所示:

如上是處理同步代碼,但是如果是異步代碼呢?繼續如下代碼測試:

new Promise((resolve, reject) => {
  setTimeout(() => {
    throw new Error('error');
  }, 100);
}).then(() => {
  // 。。。。
}).catch((e) => {
  console.log('能進來說明可以處理異常信息了');
  console.log(e);
});

然后執行結果如下所示:

可以看到,Promise也是一樣無法捕獲異步代碼中的異常信息了。

2.5 Async/Await 方式

Async/Await 也是基於Promise的,Promise是無法捕獲異步異常,因此Async/Await 也是沒有辦法捕獲的。如下測試代碼:

先看同步代碼可以捕獲到的,代碼如下:

const testFunc = function() {
  return new Promise((resolve, reject) => {
    throw new Error('error');
  });
};

async function testAsync() {
  try {
    await testFunc();
  } catch (e) {
    console.log('能進來,說明異常能處理');
    console.log(e);
  }
}

testAsync();

執行結果如下所示:

我們再看異步代碼,如下所示:

const testFunc = function() {
  setTimeout(() => {
    console.log(1111);
    return new Promise((resolve, reject) => {
      throw new Error('error');
    });
  }, 100);
};

async function testAsync() {
  try {
    await testFunc();
  } catch (e) {
    console.log('能進來,說明異常能處理');
    console.log(e);
  }
}

testAsync();

如下圖所示:

2.6 process 方式(該方式既可以處理同步代碼的異常,也可以處理異步代碼的異常)。

如下同步代碼異常:

process.on('uncaughtException', (e) => {
  console.log('我能進來,說明可以處理異常');
  console.log(e);
});

function testFunc() {
  throw new Error('error');
}

testFunc();

執行結果如下所示:

異步代碼如下所示:

process.on('uncaughtException', (e) => {
  console.log('我能進來,說明可以處理異常');
  console.log(e);
});

function testFunc() {
  setTimeout(() => {
    throw new Error('error');
  }, 100);
}

testFunc();

如下圖所示:

2.7 domain 方式

domain也可以處理任何類型異常的信息,包含同步和異步。

如下同步代碼所示:

const domain = require('domain');
const d = domain.create();

d.on('error', (e) => {
  console.log('我能進來,說明能處理異常');
  console.log(e);
});

d.run(() => {
  throw new Error('同步代碼處理');
});

如下圖所示:

異步代碼如下所示:

const domain = require('domain');
const d = domain.create();

d.on('error', (e) => {
  console.log('我能進來,說明能處理異常');
  console.log(e);
});

d.run(() => {
  setTimeout(() => {
    throw new Error('異步代碼處理');
  }, 100);
});

如下圖所示:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM