前端异常处理知识点
異常
js中執行出現錯誤會退出進程、終止腳本執行
console.log(x) console.log(123) // Uncaught ReferenceError: x is not defined 復制代碼try catch
try catch 捕獲異常
try...catch 語句將能引發錯誤的代碼放在try塊中,并且對應一個響應,就能夠捕獲異常,不會影響后續代碼運行。
try {throw new Error('test') } catch (e) {console.log(e) } console.log(1) // Error: test // 1 復制代碼try..catch 不能捕獲異步的錯誤
try { setTimeout(function () { throw new Error('test') }, 0) } catch (e) { console.log(e) } // Uncaught Error: test 復制代碼可以配合 es6 的 async/await 捕獲異步錯誤
async (req, res, next) => {try {const users = await database.users.get()// do something} catch (e) {next(e)} } 復制代碼上面代碼中,database.users.get() 是做一些異步操作,如果拋出異步錯誤,可以被 catch 方法捕獲
Promise.prototype.catch()
Promise.prototype.catch() 方法是 Promise 異步操作狀態變為 rejected 或者異步操作拋出錯誤,就會調用 catch 方法指定的回調函數,處理這個錯誤。另外,then 方法指定的回調函數,如果運行中拋出錯誤,也會被 catch 方法捕獲。
const promise = new Promise(function(resolve, reject) {throw new Error('test'); }); promise.then(function(value) { console.log(value) }).catch(function(error) { console.log(error) }); // Error: test 復制代碼上面代碼中,promise 拋出一個錯誤,就被 catch 方法指定的回調函數捕獲。
如果 Promise 狀態已經變成 resolved,再拋出錯誤是無效的。
const promise = new Promise(function(resolve, reject) {resolve('ok');throw new Error('test'); }); promise.then(function(value) { console.log(value) }).catch(function(error) { console.log(error) }); // ok 復制代碼上面代碼中,Promise 在 resolve 語句后面,再拋出錯誤,不會被捕獲,等于沒有拋出。因為 Promise 的狀態一旦改變,就永久保持該狀態,不會再變了。
Promise 會吃掉錯誤
跟傳統的 try/catch 代碼塊不同的是,如果沒有使用 catch 方法指定錯誤處理的回調函數,Promise 對象拋出的錯誤不會傳遞到外層代碼,即不會有任何反應。
const someAsyncThing = function() {return new Promise(function(resolve, reject) {// 下面一行會報錯,因為x沒有聲明resolve(x + 2);}); };someAsyncThing().then(function() {console.log('everything is great'); });setTimeout(() => { console.log(123) }, 2000); // Uncaught (in promise) ReferenceError: x is not defined // 123 復制代碼上面代碼中,someAsyncThing 函數產生的 Promise 對象,內部有語法錯誤。瀏覽器運行到這一行,會打印出錯誤提示 ReferenceError: x is not defined ,但是不會退出進程、終止腳本執行,2 秒之后還是會輸出 123 。這就是說,Promise 內部的錯誤不會影響到 Promise 外部的代碼,通俗的說法就是“Promise 會吃掉錯誤”。
不能捕獲異步錯誤
const promise = new Promise(function (resolve, reject) {setTimeout(function () { throw new Error('test') }, 0) });promise.then(function (value) { console.log(value) }).catch(function (error) { console.log(error) })setTimeout(() => { console.log(123) }, 1000) // Uncaught Error: test // 123 復制代碼上面代碼中,Promise 指定在下一輪“事件循環”再拋出錯誤。到了那個時候,Promise 的運行已經結束了,所以這個錯誤是在 Promise 函數體外拋出的,會冒泡到最外層,成了未捕獲的錯誤,且并不會影響后續腳本執行。如果是在 setTimeout 調用 reject 則 catch 可以捕獲到。
轉載于:https://juejin.im/post/5ce79ae451882521d51ec565
總結
- 上一篇: 长治美食(分享各地美食,领略不一样的山西
- 下一篇: 易语言易语言浏览器html5,易语言做浏