在任何一門語言中,都需要錯(cuò)誤處理部分。
因?yàn)樗谴_保代碼健壯性和用戶體驗(yàn)的重要部分。
JavaScript 的錯(cuò)誤處理主要包括以下幾個(gè):
try...catch 語句:這是最常用的錯(cuò)誤處理方式。try
塊包含可能會(huì)拋出錯(cuò)誤的代碼,而catch
塊則處理這些錯(cuò)誤。finally
塊中的代碼無論是否發(fā)生錯(cuò)誤都會(huì)執(zhí)行,通常用于清理資源或執(zhí)行收尾工作。
throw 語句:可以使用throw
語句手動(dòng)拋出錯(cuò)誤。拋出的錯(cuò)誤可以是任何類型,但通常是Error
對(duì)象。
錯(cuò)誤對(duì)象:JavaScript 中的錯(cuò)誤對(duì)象包含message
、name
和stack
屬性。message
是錯(cuò)誤信息,name
是錯(cuò)誤類型,stack
是堆棧跟蹤信息。
Promise 中的錯(cuò)誤處理:在處理異步操作時(shí),使用Promise
的.catch
方法來捕獲錯(cuò)誤。
async/await 中的錯(cuò)誤處理:在使用async/await
時(shí),可以結(jié)合try...catch
來處理異步操作中的錯(cuò)誤。
現(xiàn)在就來一個(gè)一個(gè)看看。
try...catch
當(dāng)我們需要解析 JSON 字符串時(shí),如果解析失敗,就捕獲并處理錯(cuò)誤:
const jsonString = '{"name": "張三", "age": 30}'; try { // 嘗試解析JSON字符串 const user = JSON.parse(jsonString); console.log(user.name); // 輸出: 張三 } catch (error) { // 處理解析錯(cuò)誤 console.error('解析JSON時(shí)出錯(cuò):', error.message); }
如果jsonString
是一個(gè)有效的 JSON 字符串,JSON.parse
會(huì)成功解析并輸出用戶的名字。
如果jsonString
是無效的 JSON 字符串,JSON.parse
會(huì)拋出一個(gè)錯(cuò)誤,catch
塊會(huì)捕獲這個(gè)錯(cuò)誤并輸出錯(cuò)誤信息。
throw 語句
假設(shè)有一個(gè)函數(shù)的參數(shù)要求數(shù)字,如果不是數(shù)字,就拋出一個(gè)錯(cuò)誤:
function divide(a, b) { if (typeof a !== 'number' || typeof b !== 'number') { throw new Error('參數(shù)必須是數(shù)字'); } if (b === 0) { throw new Error('除數(shù)不能為零'); } return a / b; } try { console.log(divide(10, 2)); // 輸出: 5 console.log(divide(10, 'a')); // 拋出錯(cuò)誤: 參數(shù)必須是數(shù)字 } catch (error) { console.error('發(fā)生錯(cuò)誤:', error.message); }
divide
函數(shù)首先檢查參數(shù)a
和b
是否為數(shù)字。
如果不是,就使用throw
語句拋出一個(gè)錯(cuò)誤。
然后,它檢查除數(shù)b
是否為零,如果是,也拋出一個(gè)錯(cuò)誤。
在try
塊中,我們調(diào)用divide
函數(shù)并捕獲任何可能拋出的錯(cuò)誤。
如果發(fā)生錯(cuò)誤,catch
塊會(huì)捕獲錯(cuò)誤并輸出錯(cuò)誤信息。
錯(cuò)誤對(duì)象
錯(cuò)誤對(duì)象是用于表示和處理錯(cuò)誤的內(nèi)置對(duì)象。
創(chuàng)建錯(cuò)誤對(duì)象:可以使用Error
構(gòu)造函數(shù)來創(chuàng)建一個(gè)新的錯(cuò)誤對(duì)象。這個(gè)構(gòu)造函數(shù)接受一個(gè)參數(shù),表示錯(cuò)誤信息。
const error = new Error('發(fā)生了錯(cuò)誤'); console.log(error.message); // 輸出: 發(fā)生了錯(cuò)誤
錯(cuò)誤對(duì)象的屬性:錯(cuò)誤對(duì)象包含幾個(gè)重要的屬性:
try { throw new Error('自定義錯(cuò)誤信息'); } catch (error) { console.log(error.message); // 輸出: 自定義錯(cuò)誤信息 console.log(error.name); // 輸出: Error console.log(error.stack); // 輸出: 堆棧跟蹤信息 }
自定義錯(cuò)誤類型:可以通過繼承Error
類來創(chuàng)建自定義的錯(cuò)誤類型。
class ValidationError extends Error { constructor(message) { super(message); this.name = 'ValidationError'; } } try { throw new ValidationError('無效的輸入'); } catch (error) { console.log(error.message); // 輸出: 無效的輸入 console.log(error.name); // 輸出: ValidationError }
使用錯(cuò)誤對(duì)象進(jìn)行錯(cuò)誤處理:在try...catch
語句中,可以捕獲并處理錯(cuò)誤對(duì)象。
function divide(a, b) { if (typeof a !== 'number' || typeof b !== 'number') { throw new Error('參數(shù)必須是數(shù)字'); } if (b === 0) { throw new Error('除數(shù)不能為零'); } return a / b; } try { console.log(divide(10, 2)); // 輸出: 5 console.log(divide(10, 'a')); // 拋出錯(cuò)誤: 參數(shù)必須是數(shù)字 } catch (error) { console.error('發(fā)生錯(cuò)誤:', error.message); }
Promise 中的錯(cuò)誤處理
前面說過,Promise 是處理異步操作的一種方式,而錯(cuò)誤處理是確保代碼健壯性的重要部分。
當(dāng)一個(gè) Promise 被拒絕(rejected)時(shí),控制權(quán)會(huì)移交到最近的拒絕處理程序(rejection handler)。
這在實(shí)際開發(fā)中非常方便。
例如,下面的代碼中,fetch 的 URL 是錯(cuò)誤的(沒有這個(gè)網(wǎng)站),.catch
對(duì)這個(gè)錯(cuò)誤進(jìn)行了處理:
fetch('https://no-such-server.blabla') .then((response) => response.json()) .catch((err) => alert(err));
正如你所看到的,.catch
不必是立即的。
它可以在一個(gè)或多個(gè).then
之后出現(xiàn)。
或者,可能該網(wǎng)站一切正常,但響應(yīng)不是有效的 JSON。
捕獲所有錯(cuò)誤的最簡(jiǎn)單的方法是,將.catch
附加到鏈的末尾:
fetch('/article/promise-chaining/user.json') .then(response => response.json()) .then(user => fetch(`https://api.github.com/users/${user.name}`)) .then(response => response.json()) .then(githubUser => new Promise((resolve, reject) => { let img = document.createElement('img'); img.src = githubUser.avatar_url; img.className = "promise-avatar-example"; document.body.append(img); setTimeout(() => { img.remove(); resolve(githubUser); }, 3000);
async/await 中的錯(cuò)誤處理
async/await
里的錯(cuò)誤處理非常直觀,可以使用傳統(tǒng)的try/catch
語句來捕獲異常。
使用try/catch
語句:在async
函數(shù)中,可以使用try/catch
語句來捕獲和處理錯(cuò)誤。try
塊包含可能會(huì)拋出錯(cuò)誤的代碼,而catch
塊則處理這些錯(cuò)誤。
async function fetchData() { try { let response = await fetch('https://api.example.com/data'); let data = await response.json(); console.log(data); } catch (error) { console.error('獲取數(shù)據(jù)時(shí)出錯(cuò):', error); } } fetchData();
處理多個(gè)異步操作中的錯(cuò)誤:如果有多個(gè)異步操作,可以在每個(gè)操作中使用try/catch
,或者在一個(gè)大的try/catch
塊中處理所有操作。
async function fetchMultipleData() { try { let response1 = await fetch('https://api.example.com/data1'); let data1 = await response1.json(); let response2 = await fetch('https://api.example.com/data2'); let data2 = await response2.json(); console.log(data1, data2); } catch (error) { console.error('獲取數(shù)據(jù)時(shí)出錯(cuò):', error); } } fetchMultipleData();
使用.catch
方法:除了try/catch
,還可以在調(diào)用async
函數(shù)時(shí)使用.catch
方法來處理錯(cuò)誤。
async function fetchData() { let response = await fetch('https://api.example.com/data'); let data = await response.json(); return data; } fetchData() .then((data) => { console.log(data); }) .catch((error) => { console.error('獲取數(shù)據(jù)時(shí)出錯(cuò):', error); });
總結(jié)
?? try...catch 語句是 JavaScript 中最常用的錯(cuò)誤處理方式。
?? 使用throw
語句手動(dòng)拋出錯(cuò)誤,拋出的錯(cuò)誤可以是任何類型,但通常是Error
對(duì)象。
?? JavaScript 中的錯(cuò)誤對(duì)象包含message
、name
和stack
屬性。
該文章在 2024/10/28 16:09:34 編輯過