当前位置: 首页 > news >正文

使用 TypeScript 改进异步操作和错误处理的策略

使用 TypeScript 改进异步操作和错误处理的策略

处理异步代码是 JavaScript 应用程序的主要内容。TypeScript 为异步操作带来类型安全,增强可预测性并减少运行时错误。本文旨在探索我们可以利用的模式来有效地管理异步操作和错误处理。

Async/Await

Async/await 语法使代码更清晰、更易读,与同步执行非常相似。TypeScript 的类型推断与此一致,确保在编译时检查变量和返回类型,从而减少可能的运行时错误。

async function fetchData(url: string): Promise<string> {try {const response = await fetch(url);if (!response.ok) {throw new Error(`Error: ${response.statusText}`);}return await response.text();} catch (error: unknown) {// 保留堆栈跟踪throw error instanceof Error ? error : new Error("Unexpected error");}
}

Promise:确保异步操作中的类型安全

TypeScript 通过对解析值和可能发生的任何错误强制执行类型来改进Promise 。这种编译时类型检查会导致异步操作中的输出更加可预测,从而显着降低意外运行时错误的风险。

const taskResult: Promise<string> = new Promise((resolve, reject) => {const someCondition = true;if (someCondition) {resolve("Success!");} else {// TypeScript 确保这是一个 Error 对象reject(new Error("Failure"));}
});

此示例演示了 TypeScript 确保检查错误对象类型的能力,从而实现细粒度和弹性的错误处理。

增强的泛型和错误处理

TypeScript 中的泛型增强了函数灵活性,同时保持了类型安全。考虑一个获取不同类型内容的异步函数。泛型允许该函数清楚地定义其返回类型,确保编译时类型安全。

enum ResponseKind {Article = "article",Comment = "comment",Error = "error",
}type ArticleResponse = {kind: ResponseKind.Article;title: string;content: string;
};type CommentResponse = {kind: ResponseKind.Comment;content: string;
};type ErrorResponse = {kind: ResponseKind.Error;message: string;
};// 使用可区分联合来定义响应类型
type ContentResponse = ArticleResponse | CommentResponse | ErrorResponse;async function getContent<T extends ContentResponse>(contentId: string
): Promise<Exclude<T, ErrorResponse>> {const response: ContentResponse = await fetchContent(contentId);if (response.kind === ResponseKind.Error) {throw new Error(response.message);}return response as Exclude<T, ErrorResponse>;
}// 将 getContent 函数与类型断言一起使用,
// 强化我们的预期返回类型,以实现更可预测的行为和类型安全。
async function displayContent(contentId: string) {try {// 这里我们断言响应的类型为 ArticleResponseconst article = await getContent<ArticleResponse>(contentId);// 对“title”属性的类型安全访问console.log(article.title);} catch (error) {console.error(error);}
}

上面的函数getContent说明了如何使用泛型在编译时实现类型安全,确保我们正确处理各种内容类型。这种方法显着降低了运行时错误的可能性。

此外,我们利用Exclude来确保getContent不返回ErrorResponse,这是 TypeScript 的类型系统如何通过设计防止某些类运行时错误的示例。

尽管 TypeScript 有强大的编译时检查,但有些错误本质上是运行时的,需要显式处理。接下来,我们将了解自定义错误处理如何充当那些无法通过编译时检查的错误的请求。

继续我们的类型安全数据获取实践,针对运行时错误制定稳健的策略至关重要。下面对自定义错误类的介绍提供了有效区分和处理此类错误的详细方法。

class BadRequestError extends Error {public statusCode: number;constructor(message: string, statusCode = 400) {super(message);this.name = "BadRequestError";// 错误请求的默认 HTTP 400 状态代码this.statusCode = statusCode;}
}type UserData = {name: string;
};
async function submitUserData(userData: UserData): Promise<void> {try {// 数据提交validateUserData(userData);} catch (error) {// 处理错误请求错误if (error instanceof BadRequestError) {console.error(`Validation failed: ${error.message}`);// 处理意外错误} else {console.error(`Unexpected error: ${error.message}`);}// 如果想从更高层的调用函数访问错误,则重新抛出错误throw error;}
}function validateUserData<T extends UserData>(data: T): void {if (!data.name) {throw new BadRequestError("Name is required");}
}

通过自定义错误类,我们可以以精细的方式处理异常,补充泛型提供的编译时类型安全性。通过结合这些策略,我们创建了一个弹性系统,在编译时和运行时维护类型安全,为我们的 TypeScript 应用程序提供全面的错误处理。

结果类型的替代错误处理

在处理异步操作时,函数式编程风格可能特别有用。Result类型或者Either模式提供了传统错误处理的结构化替代方案。这种方法将错误视为数据,将它们封装在可以通过异步流轻松传播的结果类型中。

type Success<T> = { kind: 'success', value: T };
type Failure<E> = { kind: 'failure', error: E };
type Result<T, E = Error> = Success<T> | Failure<E>;
type AsyncResult<T, E = Error> = Promise<Result<T, E>>;async function asyncComplexOperation(): AsyncResult<number> {try {// 异步逻辑const value = await someAsyncTask();return { kind: 'success', value };} catch (error) {return {kind: 'failure',error: error instanceof Error ? error : new Error('Unknown error'),};}
}

异步操作中的结构化错误处理

对于更复杂的异步应用程序,我们可能希望使用错误边界类型来处理更高级别的错误。此模式旨在与 async/await 语法很好地配合使用,允许干净且可预测地捕获错误并处理上游。

type ErrorBoundary<T, E extends Error> = {status: 'success';data: T;
} | {status: 'error';error: E;
};async function asyncHandleError<T>(fn: () => Promise<T>,createError: (message?: string) => Error
): Promise<ErrorBoundary<T, Error>> {try {const data = await fn();return { status: 'success', data };} catch (error) {const errorMessage = error instanceof Error ? error.message : 'Unknown error';return {status: 'error',error: createError(errorMessage)};}
}async function riskyAsyncOperation(): Promise<string> {const someCondition = false;if (someCondition) {throw new Error('Failure');}return 'Success';
}async function handleOperation() {const result = await asyncHandleError(riskyAsyncOperation, (message) => new Error(message));if (result.status === 'success') {console.log(result.data); } else {console.error(result.error.message);}
}handleOperation();

在ErrorBoundary模式的异步适应中,asyncHandleError函数采用异步函数并返回一个解析为成功或错误对象的Promise。这可确保以结构化和类型安全的方式处理异步错误,从而促进 TypeScript 代码中更好的错误管理实践。

总结

本文提出了使用 TypeScript 改进异步操作和错误处理的策略,从而增强代码的健壮性和可维护性。我们通过实际示例说明了这些模式,强调了它们在现实场景中的适用性。

相关文章:

  • QT基础开发笔记
  • 【Cisco Packet Tracer】DHCP/FTP/WEB/DNS实验
  • (十三)Flask之特殊装饰器详解
  • 高防cdn防护原理是什么,是否可以防护服务器吗
  • kubernetes使用nfs创建pvc部署mysql stateful的方法
  • Intellij IDEA 的安装和使用以及配置
  • 简化版Transformer
  • 高效学习 React 框架AntDesign Pro
  • 2023.11.29 -hmzx电商平台建设项目 -核销主题阶段总结
  • XUbuntu22.04之OBS30.0设置录制音频降噪(一百九十六)
  • 基于SpringBoot母婴商城
  • 【面经八股】搜广推方向:面试记录(二)
  • 1、Linux_介绍和安装
  • 时间序列预测实战(二十一)PyTorch实现TCN卷积进行时间序列预测(专为新手编写的自研架构)
  • 知识蒸馏代码实现(以MNIST手写数字体为例,自定义MLP网络做为教师和学生网络)
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • 【Leetcode】104. 二叉树的最大深度
  • 【node学习】协程
  • android 一些 utils
  • create-react-app项目添加less配置
  • CSS盒模型深入
  • CSS相对定位
  • iOS编译提示和导航提示
  • Python_OOP
  • python3 使用 asyncio 代替线程
  • Python学习笔记 字符串拼接
  • React-flux杂记
  • Spring Boot MyBatis配置多种数据库
  • thinkphp5.1 easywechat4 微信第三方开放平台
  • TypeScript迭代器
  • ucore操作系统实验笔记 - 重新理解中断
  • 程序员该如何有效的找工作?
  • 和 || 运算
  • 力扣(LeetCode)357
  • 使用putty远程连接linux
  • 智能合约开发环境搭建及Hello World合约
  • 交换综合实验一
  • 如何用纯 CSS 创作一个货车 loader
  • 如何在招聘中考核.NET架构师
  • 通过调用文摘列表API获取文摘
  • ​linux启动进程的方式
  • ​用户画像从0到100的构建思路
  • #if 1...#endif
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (16)UiBot:智能化软件机器人(以头歌抓取课程数据为例)
  • (C语言)球球大作战
  • (定时器/计数器)中断系统(详解与使用)
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (附源码)计算机毕业设计大学生兼职系统
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (十七)devops持续集成开发——使用jenkins流水线pipeline方式发布一个微服务项目
  • (算法)求1到1亿间的质数或素数
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)
  • (转)JVM内存分配 -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m