異常
異步錯誤處理
// 坑
function printTime() {
throw new Error();
}
try {
setTimeout(printTime, 1000);
console.log('done');
} catch (e) {
alert('error');
}
用try包裹setTimeout()是無效的:原因就在于調(diào)用setTimeout()函數(shù)時,傳入的printTime函數(shù)并未立刻執(zhí)行!緊接著,JavaScript 引擎會繼續(xù)執(zhí)行console.log('done');語句,而此時并沒有錯誤發(fā)生。直到1秒鐘后,執(zhí)行printTime函數(shù)時才發(fā)生錯誤,但此時除了在printTime函數(shù)內(nèi)部捕獲錯誤外,外層代碼并無法捕獲。
所以,涉及到異步代碼,無法在調(diào)用時捕獲,原因就是在捕獲的當(dāng)時,回調(diào)函數(shù)并未執(zhí)行。
表單中的錯誤處理
類似的,當(dāng)我們處理一個事件時,在綁定事件的代碼處,無法捕獲事件處理函數(shù)的錯誤。
例如,針對以下的表單:
// 坑
<form>
<input id="x"> + <input id="y">
<button id="calc" type="button">計算</button>
</form>
<script>
var $btn = $('#calc');
// 取消已綁定的事件:
$btn.off('click');
try {
$btn.click(function () {
var
x = parseFloat($('#x').val()),
y = parseFloat($('#y').val()),
r;
if (isNaN(x) || isNaN(y)) {
throw new Error('輸入有誤');
}
r = x + y;
alert('計算結(jié)果:' + r);
});
} catch (e) {
alert('輸入有誤!');
}
</script>
用戶輸入錯誤時,處理函數(shù)并未捕獲到錯誤。修復(fù)后:
$btn.click(function () {
var
x = parseFloat($('#x').val()),
y = parseFloat($('#y').val()),
r;
try {
if (isNaN(x) || isNaN(y)) {
throw new Error('輸入有誤');
}
r = x + y;
alert('計算結(jié)果:' + r);
} catch (e) {
alert('輸入有誤!');
}
});