這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 說到try...catch都覺得非常熟悉了,不就是用來捕捉代碼塊中的錯誤嘛,平時也用得比較多的。然而因為瞭解不夠多,我的面試卻栽在了一個簡單的知識點上:try...catch只能捕捉到同步執行代碼塊中的錯誤。 題目是:以下代碼有錯嗎?如果 ...
這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助
try...catch
都覺得非常熟悉了,不就是用來捕捉代碼塊中的錯誤嘛,平時也用得比較多的。然而因為瞭解不夠多,我的面試卻栽在了一個簡單的知識點上:try...catch
只能捕捉到同步執行代碼塊中的錯誤。 題目是:以下代碼有錯嗎?如果有錯,應該如何改正?
try { setTimeout(() => { throw new Error('err') }, 200); } catch (err) { console.log(err); } try { Promise.resolve().then(() => { throw new Error('err') }) } catch (err) { console.log(err); }
反正就是不知道咋回事,我之前的知識儲備中就是沒有這個知識點:try...catch
不能非同步捕獲代碼錯誤,因為它本身就是一個同步代碼塊。所以看到這道題我就懵了,平時代碼不就是這樣寫的嗎,用try...catch
來捕獲錯誤,所以當時就直接回了我不知道,感覺沒有啥錯誤。。。,面試官無奈的看了我一眼,下來可以瞭解一下,然後就沒有然後了。
下來我就趕緊查了資料,才知道try...catch
不能非同步捕獲代碼錯誤。在JavaScript中,setTimeout
是一個非同步函數,它的回調函數會在指定的延時後被放入事件隊列,等待當前執行棧清空後才執行。因此,當setTimeout
的回調函數執行並拋出錯誤時,try...catch
已經執行完畢,無法捕捉到非同步回調中的錯誤。
正確的做法是在非同步操作中直接處理錯誤,例如使用回調函數、Promises或者async/await結合try...catch
new Promise((resolve, reject) => { setTimeout(() => { try { throw new Error('err'); } catch (err) { reject(err); } }, 200); }) .then(() => { // 正常執行時的處理邏輯 }) .catch((err) => { console.log(err); // 這裡會捕捉到錯誤 });
至於第二個例子,嘗試使用try...catch
來捕捉一個在Promise鏈中拋出的錯誤。這種方式同樣是無效的,因為try...catch
不能捕捉到在Promise鏈中的非同步錯誤。
Promise對象用於表示一個非同步操作的最終完成(或失敗),及其結果值。一個Promise的狀態可能是以下幾種:
- Pending(等待態) :初始狀態,既不是成功,也不是失敗狀態。
- Fulfilled(成功態) :意味著操作成功完成。
- Rejected(失敗態) :意味著操作失敗。
在Promise中拋出一個錯誤(例如通過throw
語句)會導致Promise被拒絕(或失敗)。要正確處理這個錯誤,需要在Promise鏈中使用.catch
方法或者在一個async
函數中使用try...catch
。
// 方法一 Promise.resolve() .then(() => { throw new Error('err'); }) .catch((err) => { console.log(err); // 這裡會捕捉到錯誤 }); // 方法二 async function handleError() { try { await Promise.resolve().then(() => { throw new Error('err'); }); } catch (err) { console.log(err); // 這裡會捕捉到錯誤 } } handleError();