再见 Try/Catch,在 TypeScript 中更优雅地处理错误
原文链接:No more Try/Catch: a better way to handle errors in TypeScript
作者:Noah
译者:倔强青铜三
前言
大家好,我是倔强青铜三。是一名热情的软件工程师,我热衷于分享和传播IT技术,致力于通过我的知识和技能推动技术交流与创新,欢迎关注我,微信公众号:倔强青铜三。欢迎点赞、收藏、关注,一键三连!!!
用“错误捕获”替代 Try/Catch:TypeScript 错误处理新思路
在开发 TypeScript 应用程序时,你是否觉得传统的 Try/Catch 错误处理方式有些繁琐?最近,我在 YouTube 上看到一个有趣的视频,介绍了一种更简洁的错误处理方法。今天,我将分享视频中的核心内容,并结合自己的理解进行总结。
定义 getUser 函数用于错误处理
首先,我们定义一个简单的 getUser
函数来演示错误处理。该函数根据给定的 id
返回一个用户对象。
TypeScript复制
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 进行错误处理
将上述代码改写为使用 try/catch 的形式,代码如下:
TypeScript复制
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 的问题 ①:捕获了 try 块内的所有错误
以下代码存在问题。即使只是一个拼写错误,控制台也会显示“There was an error
”,而我只想捕获 getUser
中发生的错误。
TypeScript复制
const wait = (duration: number) => {
...
};
const getUser = async (id: number) => {
...
};
try {
const user = await getUser(1);
console.log(usr); // ← 拼写错误
// ... (大量代码)
} catch (error) {
console.log("There was an error");
}
try/catch 的问题 ②:使用 let 的陷阱
尝试使用 let
解决问题,代码如下:
TypeScript复制
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
虽然拼写错误引发了实际错误,但这段代码仍不理想,因为可能会意外重新定义 user
对象,例如:
TypeScript复制
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; // ← ❌ 可能引发错误
解决方案
使用 catchError
函数可以更简洁、更易读地处理错误。此外,user
变量是不可变的,不会引发意外错误。
TypeScript复制
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);
如果你对这种模式是否实用有疑问,可以参考视频中的详细解释。我虽然没有在实际工作中使用过这种模式,但很想知道大家的看法。因为视频评论区中也讨论过这个问题,我希望能从大家的反馈中探索最佳实践。祝大家编码愉快☀️
最后感谢阅读!欢迎关注我,微信公众号:倔强青铜三
。欢迎点赞
、收藏
、关注
,一键三连!!!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。