1.不處理直接致使程序奔潰,這顯然不是咱們想要的 2.致使請求沒法被釋放,直至鏈接超時。用戶體驗體驗很是差,咱們要作的應該是在出錯時,給用戶一個友好的提示,並記錄下這次異常,以便排查。
// 每秒鐘打印一次時間,確保程序沒有奔潰 (function loop() { console.log(new Date().getTime()) setTimeout(function () { loop() }, 1000) })() // 模擬同步代碼塊內出現異常 let syncError = () => { throw new Error('Sync Error') } // 模擬異步代碼塊內出現異常 let asyncError = () => { setTimeout(function () { throw new Error('Async Error') }, 100) }
try { syncError() } catch (e) { /*處理異常*/ console.log(e.message) } console.log('異常被捕獲了,我能夠繼續執行')
可是try catch方式沒法處理異步代碼塊內出現的異常,你能夠理解爲執行catch時,異常尚未發生。javascript
try { asyncError() } catch (e) { /*異常沒法被捕獲,致使進程退出*/ console.log(e.message) }
fs.mkdir('/dir', function (e) { if (e) { /*處理異常*/ console.log(e.message) } else { console.log('建立目錄成功') } })
let events = require("events"); //建立一個事件監聽對象 let emitter = new events.EventEmitter(); //監聽error事件 emitter.addListener("error", function (e) { /*處理異常*/ console.log(e.message) }); //觸發error事件 emitter.emit("error", new Error('出錯啦'));
new Promise((resolve, reject) => { syncError() /* or try{ syncError() }catch(e){ reject(e) } */ }) .then(() => { //... }) .catch((e) => { /*處理異常*/ console.log(e.message) })
Promise一樣沒法處理異步代碼塊中拋出的異常java
new Promise((resolve, reject) => { asyncError() }) .then(() => { //... }) .catch((e) => { /*異常沒法被捕獲,致使進程退出*/ console.log(e.message) })
Async/Await是基於Promise的,因此Promise沒法捕獲的異常,Async/Await一樣沒法捕獲dom
var sleep = function (time) { return new Promise(function (resolve, reject) { syncError() }) }; (async function () { try { await sleep(100); } catch (e) { /*處理異常*/ console.log(e.message) } })()
process方式能夠捕獲任何異常(無論是同步代碼塊中的異常仍是異步代碼塊中的異常)異步
process.on('uncaughtException', function (e) { /*處理異常*/ console.log(e.message) }); asyncError() syncError()
process方式雖然能夠捕獲任何類型的異常,可是process太過笨重,除了記錄下錯誤信息,其餘地方不適合使用,domain這個也能夠處理任何類型異常的模塊,顯然是一個不錯的選擇。async
let domain = require('domain') let d = domain.create() d.on('error', function (e) { /*處理異常*/ console.log(e.message) }) d.run(asyncError) d.run(syncError)