try-catch
捕獲異常的時候只可以捕獲同步運行時的錯誤和異常,不能捕獲語法錯誤和異步執行代碼的錯誤和異常。javascript
try{
// 同步代碼出錯
} catch(err) {
// 捕獲同步錯誤
}
複製代碼
程序代碼html
try {
throw new Error('拋出異常')
} catch (err) {
console.log("捕獲到了異常"+err)
}
複製代碼
執行結果前端
捕獲到了異常Error: 拋出異常
複製代碼
少寫一個單引號,構造語法錯誤java
try {
console.log('1)
} catch (err) {
console.log("捕獲到了異常"+err)
}
複製代碼
執行結果node
console.log('1)
^^
SyntaxError: Invalid or unexpected token
複製代碼
通常而言,編輯器會有語法檢查,這個只是 try-catch
沒法捕獲的例子,實際中不多出現 git
使用 setTimeout
異步執行拋出錯誤github
try {
setTimeout(()=>{
throw new Error('異步錯誤')
})
} catch (err) {
console.log("捕獲到了異常"+err)
}
複製代碼
執行結果ajax
throw new Error('異步錯誤')
^
Error: 異步錯誤
at Timeout.setTimeout [as _onTimeout] (D:\fcode\try-catch.js:7:15)
複製代碼
JavaScript代碼執行的過程promise
try-catch
是同步執行代碼,在第一階段的時候執行完畢,異步錯誤或者異常是在第二階段執行的,同步代碼不可能執行它執行完之後的任務,因此捕獲不到。promise
相比於 try-catch
更加容易捕獲異步錯誤和異常。下面是一些注意點 瀏覽器
return new Error('錯誤')
的方式返回異常不能被下一個catch
捕獲到,這裏返回的promise
是resolve
狀態,會被傳遞下去被then
捕獲,只有throw new Error()
才能被下一個catch
捕獲var promise = new Promise((resolve, reject) => {
resolve('1')
})
promise.then((data) => {
return new Error('錯誤')
}).catch((err) => {
console.log('不會執行')
}).then((data) => {
console.log('打印以前返回的錯誤', data)
})
// 打印以前返回的錯誤 Error: 錯誤
// at promise.then (4.html:16)
複製代碼
then(success, error)
then
能夠由兩個處理函數,第一個用來處理resolved
狀態的promise
返回值,第二個用來處理rejected
狀態的promise
返回值,這裏處理的是鏈式調用的返回的前一個promise
var promise = new Promise((resolve, reject) => {
reject('錯誤')
})
promise.then((data)=>{
console.log('不會執行,promise狀態是rejected')
}, (err)=>{
// 捕獲到錯誤
console.log(err) // 錯誤
}).catch((err) => {
// 鏈式調用的前一個promise返回是一個resolve狀態
console.log('不能捕獲到錯誤')
})
複製代碼
then
中沒有指定處理rejected
狀態的函數時,錯誤狀態會一直傳遞下去直到被處理,要是沒有處理不會被window
捕獲,直接控制檯報錯...window.addEventListener('error', (e) => {
console.log(e)
})
var promise = new Promise((resolve, reject) => {
reject('錯誤')
})
promise.then((data)=>{
console.log('未對錯誤處理')
}).catch((err) => {
// 執行
console.log('上一個then中缺省處理錯誤的函數,錯誤會被封裝成新的promise向下傳遞', err)
})
promise.then((data)=>{
console.log('不處理,也沒有後續,錯誤會被window捕捉到')
})
複製代碼
.then
的第二個處理錯誤的函數捕獲不了第一個處理成功的函數拋出的錯誤,然後續的 .catch
能夠捕獲以前的錯誤var promise = new Promise((resolve, rejected) => {
resolve(1)
})
promise.then((data)=>{
throw new Error('2')
}, (err) => {
console.log('不能捕獲,then中第一個成功回調返回的錯誤')
}).catch((err)=>{
console.log('能夠捕獲上一個then中成功或者錯誤處理函數中拋出的錯誤')
})
複製代碼
process.on('uncaughtException', function (err) {
// todo
});
複製代碼
上述代碼必定要加在最前面,當 Node 發現一個未捕獲的異常時,會觸發這個事件。可是在 uncaughtException
的回調事件中會丟失環境的上下文。
當 JS
運行時錯誤發生時,window
會觸發一個 ErrorEvent
接口的 error
事件,並執行 window.onerror()
window.onerror = function(msg, file, line, col, error) {
// msg:錯誤信息(字符串)。
// file:發生錯誤的腳本URL(字符串)
// lineno:發生錯誤的行號(數字)
// col:發生錯誤的列號(數字)
// error:Error對象(對象)
// todo
}
複製代碼
當一項資源(如圖片或腳本)加載失敗,加載資源的元素會觸發一個 Event
接口的 error
事件,並執行該元素上的onerror()
處理函數。這些 error
事件不會向上冒泡到 window
這樣用 onerror()
沒法捕捉到,此時可使用 window.addEventListener
捕獲。
網絡請求異常不是註冊在DOM交互事件,不會向上冒泡,在事件的捕獲階段處理。
window.addEventListener('error', (error) => {
console.log('捕獲到異常:', error);
}, true)
複製代碼
除了 try-catch
和 promise
的場景還會有其餘的一些異常處理,在平時接觸和閱讀文章的時候瞭解到還有
這些實際遇到的較少,尚未太多的實戰經驗暫作記錄,等有了經驗以後再作補充。
參考文章以下: