前言
大家好,我是倔強(qiáng)青銅三。是一名熱情的軟件工程師,我熱衷于分享和傳播IT技術(shù),致力于通過(guò)我的知識(shí)和技能推動(dòng)技術(shù)交流與創(chuàng)新,歡迎關(guān)注我,微信公眾號(hào):倔強(qiáng)青銅三。歡迎點(diǎn)贊、收藏、關(guān)注,一鍵三連!?。?/p>
用“錯(cuò)誤捕獲”替代 Try/Catch:TypeScript 錯(cuò)誤處理新思路
在開(kāi)發(fā) TypeScript 應(yīng)用程序時(shí),你是否覺(jué)得傳統(tǒng)的 Try/Catch 錯(cuò)誤處理方式有些繁瑣?最近,我在 YouTube 上看到一個(gè)有趣的視頻,介紹了一種更簡(jiǎn)潔的錯(cuò)誤處理方法。今天,我將分享視頻中的核心內(nèi)容,并結(jié)合自己的理解進(jìn)行總結(jié)。
定義 getUser 函數(shù)用于錯(cuò)誤處理
首先,我們定義一個(gè)簡(jiǎn)單的 getUser
函數(shù)來(lái)演示錯(cuò)誤處理。該函數(shù)根據(jù)給定的 id
返回一個(gè)用戶對(duì)象。
const wait = (duration: number) => {
return new Promise((resolve) => {
setTimeout(resolve, duration);
});
};
const getUser = async (id: number) => {
await wait(1000);
if (id === 2) {
throw new Error("404 - User does not exist");
}
return { id, name: "Noah" };
};
const user = await getUser(1);
console.log(user); // { id: 1, name: "Noah" }
使用 try/catch 進(jìn)行錯(cuò)誤處理
將上述代碼改寫為使用 try/catch 的形式,代碼如下:
const wait = (duration: number) => {
...
};
const getUser = async (id: number) => {
...
};
try {
const user = await getUser(1);
console.log(user); // { id: 1, name: "Noah" }
} catch (error) {
console.log("There was an error");
}
try/catch 的問(wèn)題 ①:捕獲了 try 塊內(nèi)的所有錯(cuò)誤
以下代碼存在問(wèn)題。即使只是一個(gè)拼寫錯(cuò)誤,控制臺(tái)也會(huì)顯示“There was an error
”,而我只想捕獲 getUser
中發(fā)生的錯(cuò)誤。
const wait = (duration: number) => {
...
};
const getUser = async (id: number) => {
...
};
try {
const user = await getUser(1);
console.log(usr); // ← 拼寫錯(cuò)誤
// ... (大量代碼)
} catch (error) {
console.log("There was an error");
}
try/catch 的問(wèn)題 ②:使用 let 的陷阱
嘗試使用 let
解決問(wèn)題,代碼如下:
const wait = (duration: number) => {
...
};
const getUser = async (id: number) => {
...
};
let user;
try {
user = await getUser(1);
// ... (大量代碼)
} catch (error) {
console.log("There was an error");
}
console.log(usr); // ← ReferenceError: Can't find variable: usr
雖然拼寫錯(cuò)誤引發(fā)了實(shí)際錯(cuò)誤,但這段代碼仍不理想,因?yàn)榭赡軙?huì)意外重新定義 user
對(duì)象,例如:
const wait = (duration: number) => {
...
};
const getUser = async (id: number) => {
...
};
let user;
try {
user = await getUser(1);
// ... (大量代碼)
} catch (error) {
console.log("There was an error");
}
user = 1; // ← ? 可能引發(fā)錯(cuò)誤
解決方案
使用 catchError
函數(shù)可以更簡(jiǎn)潔、更易讀地處理錯(cuò)誤。此外,user
變量是不可變的,不會(huì)引發(fā)意外錯(cuò)誤。
const wait = (duration: number) => {
...
};
const getUser = async (id: number) => {
...
};
const catchError = async <T>(promise: Promise<T>): Promise<[undefined, T] | [Error]> => {
return promise
.then((data) => {
return [undefined, data] as [undefined, T];
})
.catch((error) => {
return [error];
});
};
const [error, user] = await catchError(getUser(1));
if (error) {
console.log(error);
}
console.log(user);
如果你對(duì)這種模式是否實(shí)用有疑問(wèn),可以參考視頻中的詳細(xì)解釋。