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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/186090.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux下删除当前目录下的所有目录

Linux下删除当前目录下的所有目录 Linux下删除当前目录下的所有目录&#xff0c;可以使用命令&#xff1a;rm -rf ./* rm -rf ./*可以得知rm -rf ./命令是删除当前目录下的所有文件和文件夹&#xff0c;但不会删除根目录下的文件。其中&#xff0c;".“代表当前目录&…

【加密相册】 隐私协议

【加密相册】隐私协议 1.个人信息的收集和使用 我们的应用程序不会收集用户的个人信息&#xff0c;包括姓名、地址、电子邮件地址、电话号码等。我们不会追踪用户的位置信息或共享用户的个人信息。 2. 非个人化信息的收集和使用 我们的应用程序可能会收集一些非个人化信息&a…

Pycharm新手开发指南

文章目录 前言一、常用功能介绍二、常用高效pycharm使用方法关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试资料六、Python兼职渠道 前言…

武汉芯源半导体首款车规级MCU,CW32A030C8T7通过AEC-Q100测试考核

近日&#xff0c;武汉芯源半导体正式发布首款基于Cortex-M0内核的CW32A030C8T7车规级MCU&#xff0c;这是武汉芯源半导体首款通过AEC-Q100 (Grade 2)车规标准的主流通用型车规MCU产品。 CW32A030C8T7通过AEC-Q100车规可靠性测试 作为武汉芯源半导体首款车规级MCU产品&#xff0…

Spring整合web环境

目录 Javaweb三大组件及环境特点 Spring整合web环境的思路及实现 Spring的web开发组件spring-web MVC框架思想及其设计思路 Javaweb三大组件及环境特点 Spring整合web环境的思路及实现 package com.xfy.listener;import com.xfy.config.SpringConfig; import org.springfra…

Linux中的fork()函数的面试题目

1.面试题目1 (1)fork 以后&#xff0c;父进程打开的文件指针位置在子进程里面是否一样&#xff1f;(先open再fork) (2)能否用代码简单的验证一下? (3)先fork再打开文件父子进程是否共享偏移量?父进程打开的文件指针位置在子进程里面是否一样&#xff1f;能否用代码简单验证一…

代理模式 1、静态代理 2、动态代理 jdk自带动态代理 3、Cglib代理

文章目录 代理模式1、静态代理2、动态代理jdk自带动态代理 3、Cglib代理 来和大家聊聊代理模式 代理模式 代理模式&#xff1a;即通过代理对象访问目标对象&#xff0c;实现目标对象的方法。这样做的好处是&#xff1a;可以在目标对象实现的基础上&#xff0c;增强额外的功能操…

【Openstack Train安装】八、placement安装

Placement 肩负着这样的历史使命&#xff0c;最早在 Newton 版本被引入到 openstack/nova repo&#xff0c;以 API 的形式进行孵化&#xff0c;所以也经常被称呼为 Placement API。它参与到 nova-scheduler 选择目标主机的调度流程中&#xff0c;负责跟踪记录 Resource Provide…

java学校高校运动会报名信息管理系统springboot+jsp

课题研究方案&#xff1a; 结合用户的使用需求&#xff0c;本系统采用运用较为广泛的Java语言&#xff0c;springboot框架&#xff0c;HTML语言等关键技术&#xff0c;并在idea开发平台上设计与研发创业学院运动会管理系统。同时&#xff0c;使用MySQL数据库&#xff0c;设计实…

五种多目标优化算法(MOPSO、MOAHA、NSGA2、NSGA3、MOGWO)求解微电网多目标优化调度(MATLAB)

一、多目标优化算法简介 &#xff08;1&#xff09;多目标粒子群优化算法MOPSO 多目标应用&#xff1a;基于多目标粒子群优化算法MOPSO求解微电网多目标优化调度&#xff08;MATLAB代码&#xff09;-CSDN博客 &#xff08;2&#xff09;多目标人工蜂鸟算法&#xff08;MOAHA…

QTreeWidgetItem 是 Qt 框架中的一个类,用于在树形控件中表示和操作树节点

QTreeWidgetItem 是 Qt 框架中的一个类&#xff0c;用于在树形控件中表示和操作树节点。 QTreeWidgetItem 代表树形控件中的一个节点&#xff0c;可以包含子节点、显示文本、图标和其他相关数据。它通常用于 QTreeWidget 或 QTreeWidget 的派生类中&#xff0c;用于构建和管理…

nexus制品库的介绍及详细部署使用

一、nexus 介绍 Nexus 是一个强大的仓库管理工具&#xff0c;用于管理和分发 Maven、npm、Docker 等软件包。它提供了一个集中的存储库&#xff0c;用于存储和管理软件包&#xff0c;并提供了版本控制、访问控制、构建和部署等功能。 Nexus 可以帮助开发团队提高软件包管理的效…

Arduino驱动SHT-C3数字温湿度传感器(温湿度传感器)

目录 1、传感器特性 2、硬件原理图 3、控制器和传感器连线图 4、驱动程序 SHTC3是业内知名的Sensirion公司推出的新一代数字温湿度传感器,脱胎于久经市场考验并取得斐然成绩的 SHTC1。传承了盛思锐湿度和温度传感器在业界有口皆碑的质量和可靠性,SHTC3 可在广阔的测量范…

【Linux】cd 命令使用

cd&#xff08;英文全拼&#xff1a;change directory&#xff09;命令用于改变当前工作目录的命令&#xff0c;切换到指定的路径。 ~ 也表示为 home 目录 的意思。. 则是表示目前所在的目录。.. 则表示目前目录位置的上一层目录。 语法 cd [目录] 命令选项及作用 执行令 …

C++——AVL树

作者&#xff1a;几冬雪来 时间&#xff1a;2023年11月30日 内容&#xff1a;C板块AVL树讲解 目录 前言&#xff1a; AVL树与搜索二叉树之间的关系&#xff1a; AVL树概念&#xff1a; 插入结点&#xff1a; 平衡因子&#xff1a; 旋转&#xff1a; 双旋&#xff1a; …

基于SpringBoot母婴商城

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本母婴商城系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&am…

网络基础『发展 ‖ 协议 ‖ 传输 ‖ 地址』

&#x1f52d;个人主页&#xff1a; 北 海 &#x1f6dc;所属专栏&#xff1a; 神奇的网络世界 &#x1f4bb;操作环境&#xff1a; CentOS 7.6 阿里云远程服务器 文章目录 &#x1f324;️前言&#x1f326;️正文1.网络发展1.1.背景1.2.类型 2.网络协议2.1.什么是协议2.2.协议…

SpringCloud核心组件

Eureka 注册中心&#xff0c;服务的注册与发现 Feign远程调用 Ribbon负载均衡&#xff0c;默认轮询 Hystrix 熔断 降级 Zuul微服务网关&#xff08;这个组件负责网络路由&#xff0c;可以做统一的降级、限流、认证授权、安全&#xff09; Eureka 微服务的功能主要有以下几…

Hermite矩阵的特征值估计——courant-fischer定理

Hermite矩阵的特征值估计——courant-fischer定理 一、courant-fischer定理&#xff08;min-max定理&#xff09; 将hermite矩阵的特征值表示为一系列最优化问题的解。 一个函数 R ( x ) x H A x x H x R(x)\frac{x^HAx}{x^Hx} R(x)xHxxHAx​&#xff0c;称为Rayleigh商&am…

代码随想录二刷 |字符串 |反转字符串II

代码随想录二刷 &#xff5c;字符串 &#xff5c;反转字符串II 题目描述解题思路 & 代码实现 题目描述 541.反转字符串II 给定一个字符串 s 和一个整数 k&#xff0c;从字符串开头算起&#xff0c;每计数至 2k 个字符&#xff0c;就反转这 2k 字符中的前 k 个字符。 如果…