前端异常处理知识点
異常
js中執(zhí)行出現(xiàn)錯誤會退出進程、終止腳本執(zhí)行
console.log(x) console.log(123) // Uncaught ReferenceError: x is not defined 復(fù)制代碼try catch
try catch 捕獲異常
try...catch 語句將能引發(fā)錯誤的代碼放在try塊中,并且對應(yīng)一個響應(yīng),就能夠捕獲異常,不會影響后續(xù)代碼運行。
try {throw new Error('test') } catch (e) {console.log(e) } console.log(1) // Error: test // 1 復(fù)制代碼try..catch 不能捕獲異步的錯誤
try { setTimeout(function () { throw new Error('test') }, 0) } catch (e) { console.log(e) } // Uncaught Error: test 復(fù)制代碼可以配合 es6 的 async/await 捕獲異步錯誤
async (req, res, next) => {try {const users = await database.users.get()// do something} catch (e) {next(e)} } 復(fù)制代碼上面代碼中,database.users.get() 是做一些異步操作,如果拋出異步錯誤,可以被 catch 方法捕獲
Promise.prototype.catch()
Promise.prototype.catch() 方法是 Promise 異步操作狀態(tài)變?yōu)?rejected 或者異步操作拋出錯誤,就會調(diào)用 catch 方法指定的回調(diào)函數(shù),處理這個錯誤。另外,then 方法指定的回調(diào)函數(shù),如果運行中拋出錯誤,也會被 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 復(fù)制代碼上面代碼中,promise 拋出一個錯誤,就被 catch 方法指定的回調(diào)函數(shù)捕獲。
如果 Promise 狀態(tài)已經(jīng)變成 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 復(fù)制代碼上面代碼中,Promise 在 resolve 語句后面,再拋出錯誤,不會被捕獲,等于沒有拋出。因為 Promise 的狀態(tài)一旦改變,就永久保持該狀態(tài),不會再變了。
Promise 會吃掉錯誤
跟傳統(tǒng)的 try/catch 代碼塊不同的是,如果沒有使用 catch 方法指定錯誤處理的回調(diào)函數(shù),Promise 對象拋出的錯誤不會傳遞到外層代碼,即不會有任何反應(yīng)。
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 復(fù)制代碼上面代碼中,someAsyncThing 函數(shù)產(chǎn)生的 Promise 對象,內(nèi)部有語法錯誤。瀏覽器運行到這一行,會打印出錯誤提示 ReferenceError: x is not defined ,但是不會退出進程、終止腳本執(zhí)行,2 秒之后還是會輸出 123 。這就是說,Promise 內(nèi)部的錯誤不會影響到 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 復(fù)制代碼上面代碼中,Promise 指定在下一輪“事件循環(huán)”再拋出錯誤。到了那個時候,Promise 的運行已經(jīng)結(jié)束了,所以這個錯誤是在 Promise 函數(shù)體外拋出的,會冒泡到最外層,成了未捕獲的錯誤,且并不會影響后續(xù)腳本執(zhí)行。如果是在 setTimeout 調(diào)用 reject 則 catch 可以捕獲到。
轉(zhuǎn)載于:https://juejin.im/post/5ce79ae451882521d51ec565
總結(jié)
- 上一篇: 长治美食(分享各地美食,领略不一样的山西
- 下一篇: gitlab+svn自动增量发包