編寫JavaScript代碼時,咱們要時刻牢記,JavaScript引擎是一個事件驅動的執行引擎,代碼老是以單線程執行,而回調函數的執行須要等到下一個知足條件的事件出現後,纔會被執行。異步
例如,setTimeout()
函數能夠傳入回調函數,並在指定若干毫秒後執行:函數
function printTime() { console.log('It is time!'); } setTimeout(printTime, 1000); console.log('done');
上面的代碼會先打印done
,1秒後纔會打印It is time!
。spa
若是printTime()
函數內部發生了錯誤,咱們試圖用try包裹setTimeout()
是無效的:線程
'use strict'; function printTime() { throw new Error(); } try { setTimeout(printTime, 1000); console.log('done'); } catch (e) { alert('error'); }
緣由就在於調用setTimeout()
函數時,傳入的printTime
函數並未馬上執行!緊接着,JavaScript引擎會繼續執行console.log('done');
語句,而此時並無錯誤發生。直到1秒鐘後,執行printTime
函數時才發生錯誤,但此時除了在printTime
函數內部捕獲錯誤外,外層代碼並沒有法捕獲。code
因此,涉及到異步代碼,沒法在調用時捕獲,緣由就是在捕獲的當時,回調函數並未執行。orm
相似的,當咱們處理一個事件時,在綁定事件的代碼處,沒法捕獲事件處理函數的錯誤。blog
例如,針對如下的表單:事件
<form> <input id="x"> + <input id="y"> <button id="calc" type="button">計算</button> </form>
咱們用下面的代碼給button綁定click事件:ip
'use strict'; 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('計算結果:' + r); }); } catch (e) { alert('輸入有誤!'); }
可是,用戶輸入錯誤時,處理函數並未捕獲到錯誤input