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

【前端】在 TypeScript 中使用 AbortController 取消异步请求

在 TypeScript 中使用 AbortController 来取消异步请求,尤其是像 fetch 这样的请求,可以提供一种优雅的方式来中止长时间运行的操作。下面是一个详细的步骤说明,展示如何在 TypeScript 中使用 AbortController 取消 fetch 请求。

步骤 1:创建 AbortController 实例

首先,你需要创建一个 AbortController 实例,并从中获取 signal 对象。这个 signal 对象将在请求中使用,以便在需要时取消请求。

const controller = new AbortController();
const signal = controller.signal;

步骤 2:发送带有 signal 的请求

当使用 fetch 发送请求时,传递 signal 作为选项的一部分。如果请求被取消,fetch 将会抛出一个带有 name 属性为 "AbortError" 的错误。

fetch('/api/data', { signal }).then(response => {if (!response.ok) {throw new Error(`HTTP error! Status: ${response.status}`);}return response.json();}).then(data => {console.log(data);}).catch(error => {if (error.name === 'AbortError') {console.log('Fetch operation was aborted');} else {console.error('Fetch operation failed:', error);}});

步骤 3:取消请求

在某个时刻,如果你决定要取消请求,只需调用 controller.abort() 方法即可。

setTimeout(() => {controller.abort();
}, 3000); // 取消请求将在3秒后发生

示例:完整的代码示例

下面是一个完整的示例,展示了如何使用 AbortController 来取消一个 fetch 请求:

// 示例:使用 AbortController 取消 fetch 请求
const controller = new AbortController();
const signal = controller.signal;// 在3秒后取消请求
setTimeout(() => {controller.abort();
}, 3000);// 发送带有 signal 的请求
fetch('/api/data', { signal }).then(response => {if (!response.ok) {throw new Error(`HTTP error! Status: ${response.status}`);}return response.json();}).then(data => {console.log('Received data:', data);}).catch(error => {if (error.name === 'AbortError') {console.log('Fetch operation was aborted');} else {console.error('Fetch operation failed:', error);}});

在使用 AbortController 取消请求后,如果需要重新尝试发送请求,可以采用几种不同的策略。下面将介绍如何在 TypeScript 中实现重新尝试的逻辑。

1. 手动重新尝试

最简单的方法是在请求被取消后手动重新触发请求。这种方法适用于你知道何时应该重新尝试的情况,比如在某些用户操作之后。

const controller = new AbortController();
const signal = controller.signal;// 发送带有 signal 的请求
fetch('/api/data', { signal }).then(response => {if (!response.ok) {throw new Error(`HTTP error! Status: ${response.status}`);}return response.json();}).then(data => {console.log('Received data:', data);}).catch(error => {if (error.name === 'AbortError') {console.log('Fetch operation was aborted');// 手动重新尝试setTimeout(() => {controller = new AbortController();signal = controller.signal;fetch('/api/data', { signal }).then(response => {if (!response.ok) {throw new Error(`HTTP error! Status: ${response.status}`);}return response.json();}).then(data => {console.log('Retried and received data:', data);}).catch(error => {console.error('Retry failed:', error);});}, 5000); // 5秒后重新尝试} else {console.error('Fetch operation failed:', error);}});
2. 使用重试库

另一种方法是使用重试库,例如 p-retry 或者 retry,它们可以自动处理重试逻辑,并提供灵活的配置选项。

示例:使用 p-retry

首先安装 p-retry

npm install p-retry

然后在代码中使用它:

import retry from 'p-retry';async function fetchData(signal: AbortSignal): Promise<any> {return fetch('/api/data', { signal }).then(res => res.json());
}retry(() => fetchData(signal),{ retries: 3, factor: 2, minTimeout: 1000, maxTimeout: 3000 }
).then(data => {console.log('Received data:', data);}).catch(error => {console.error('Fetch operation failed:', error);});
3. 自定义重试逻辑

你也可以自己编写重试逻辑,根据需要调整重试次数、间隔时间等参数。

const MAX_RETRIES = 3;
const RETRY_INTERVAL = 1000; // 间隔时间(毫秒)async function fetchData(signal: AbortSignal): Promise<any> {return fetch('/api/data', { signal }).then(res => res.json());
}async function retryFetch(signal: AbortSignal, retriesLeft: number = MAX_RETRIES): Promise<any> {try {return await fetchData(signal);} catch (error) {if (error.name === 'AbortError' && retriesLeft > 0) {console.log(`Fetch operation was aborted, retrying... (${retriesLeft} attempts left)`);await new Promise(resolve => setTimeout(resolve, RETRY_INTERVAL));return retryFetch(signal, retriesLeft - 1);} else {throw error;}}
}retryFetch(signal).then(data => {console.log('Received data:', data);}).catch(error => {console.error('Fetch operation failed:', error);});
4. 使用 AbortController 的组合策略

你还可以结合使用 AbortController 和重试逻辑,以实现更复杂的场景。例如,在某些条件下取消请求,并在满足一定条件时重新尝试。

const controller = new AbortController();
const signal = controller.signal;// 在满足某些条件下取消请求
setTimeout(() => {if (/* 某些条件 */) {controller.abort();}
}, 3000);// 发送带有 signal 的请求
fetch('/api/data', { signal }).then(response => {if (!response.ok) {throw new Error(`HTTP error! Status: ${response.status}`);}return response.json();}).then(data => {console.log('Received data:', data);}).catch(error => {if (error.name === 'AbortError') {console.log('Fetch operation was aborted');// 根据条件重新尝试if (/* 满足重新尝试的条件 */) {const newController = new AbortController();const newSignal = newController.signal;fetch('/api/data', { signal: newSignal }).then(response => {if (!response.ok) {throw new Error(`HTTP error! Status: ${response.status}`);}return response.json();}).then(data => {console.log('Retried and received data:', data);}).catch(error => {console.error('Retry failed:', error);});}} else {console.error('Fetch operation failed:', error);}});

注意事项

  • 兼容性:请确保你的浏览器或 Node.js 版本支持 AbortController。对于不支持的环境,你可能需要考虑使用 polyfills。
  • 信号传播:如果你在请求中使用了中间件(例如代理服务器),请注意 AbortController 的信号可能不会被正确传播。在这种情况下,你可能需要手动处理信号的传播。
  • 资源释放:取消请求后,确保适当释放资源。例如,如果请求涉及文件上传,取消请求后应确保删除临时文件。

使用 AbortController 的好处

  • 更好的用户体验:用户可以在长时间的请求未完成前取消请求,减少无响应的情况。
  • 资源管理:可以避免因长时间未完成的请求而导致的资源浪费。
  • 灵活性:为异步操作提供了一种灵活的控制机制。

通过这种方式,你可以有效地在 TypeScript 中使用 AbortController 来管理异步请求的生命周期。

相关文章:

【前端】在 TypeScript 中使用 AbortController 取消异步请求

在 TypeScript 中使用 AbortController 来取消异步请求&#xff0c;尤其是像 fetch 这样的请求&#xff0c;可以提供一种优雅的方式来中止长时间运行的操作。下面是一个详细的步骤说明&#xff0c;展示如何在 TypeScript 中使用 AbortController 取消 fetch 请求。 步骤 1&…...

k8s知识点总结

docker 名称空间 分类 Docker中的名称空间用于提供进程隔离&#xff0c;确保容器之间的资源相互独立。主要分类包括&#xff1a; PID Namespace&#xff1a;进程ID隔离&#xff0c;使每个容器有自己的进程树&#xff0c;容器内的进程不会干扰其他容器或主机上的进程。 NET Nam…...

论文阅读:三星-TinyClick

《Single-Turn Agent for Empowering GUI Automation》 赋能GUI自动化的单轮代理 摘要 我们介绍了一个用于图形用户界面&#xff08;GUI&#xff09;交互任务的单轮代理&#xff0c;使用了视觉语言模型Florence-2-Base。该代理的主要任务是识别与用户指令相对应的UI元素的屏幕…...

Windows on ARM上使用sherpa-onnx实现语音识别

Windows on ARM上使用sherpa-onnx实现语音识别 下载模型准备声音文件测试下载模型 模型所在的地址在这里(),通过git命令将模型下载下来 模型:hfd地址 git clone https://hf-mirror.com/csukuangfj/sherpa-onnx-streaming-paraformer-bilingual-zh-en将如下的代码保存成一个…...

Unity 打包AB Timeline 引用丢失,错误问题

1、裁剪 在 link.xml 添加 <assembly fullname"Unity.Timeline" preserve"all"/> 上面这一步我其实做了&#xff0c;但还是不行&#xff0c;各种搜索&#xff0c;不得解&#xff0c;还有创建一个空的Timeline 放到 Resources目录下的&#xff0c;也…...

【Kettle的安装与使用】使用Kettle实现mysql和hive的数据传输(使用Kettle将mysql数据导入hive、将hive数据导入mysql)

文章目录 一、安装1、解压2、修改字符集3、启动 二、实战1、将hive数据导入mysql2、将mysql数据导入到hive 一、安装 Kettle的安装包在文章结尾 1、解压 在windows中解压到一个非中文路径下 2、修改字符集 修改 spoon.bat 文件 "-Dfile.encodingUTF-8"3、启动…...

STM32的hal库在实现延时函数(例如:Delay_ms 等)为什么用滴答定时(Systick)而不是定时器定时中断,也不是RTC?

STM32的HAL库在实现延时函数&#xff08;如Delay_ms等&#xff09;时选择使用滴答定时器&#xff08;Systick&#xff09;而非定时器定时中断或RTC&#xff08;实时时钟&#xff09;&#xff0c;主要基于以下几个原因&#xff1a; Systick定时器的优势 集成在NVIC中&#xff…...

刚刚买的域名被DNS劫持了怎么处理

在当今数字化的时代&#xff0c;域名作为网络世界的重要标识&#xff0c;对于个人和企业的在线业务都至关重要。然而&#xff0c;有时会遭遇令人头疼的问题&#xff0c;比如新买的域名被DNS劫持。这不仅会影响网站的正常访问&#xff0c;还可能导致用户信息泄露、业务受损等严重…...

递归 算法专题

递归题目技巧 什么是递归 函数自己调用自己的情况为什么会用到递归 本质: 主问题, 可以拆分成相同的子问题 子问题, 又可以拆分出相同的子问题如何理解递归? 宏观的看待递归的过程 1)不要在意递归的细节展开图 2)把递归的函数当成一个黑盒 3)相信这个黑盒一定能够完成这个任务…...

Logstash 迁移索引元数据(设置和映射)

https://help.aliyun.com/zh/es/use-cases/use-logstash-to-migrate-full-or-incremental-data-from-self-managed-elasticsearch-to-alibaba-cloud-elasticsearch 在进行数据迁移时&#xff0c;Logstash会帮助您自动创建索引&#xff0c;但是自动创建的索引可能与您待迁移的索…...

用python将pdf转成图片转换成对应的word文件

*科管系统**报告只能上传word&#xff0c;但是有些盖章文件只有pdf版本&#xff0c;因此有这个需求&#xff0c;目前市面上没这软件&#xff0c;只能自己python写一个。 要将PDF中的页面以图片的形式存储到Word文档中&#xff0c;你需要完成以下几个步骤&#xff1a; 从PDF中…...

list(c++)

list介绍 list是STL容器中的容器&#xff0c;且元素在容器中的位置是分散的并与大小无关。list的底层是双向链表&#xff0c;其优势是在任意位置插入和删除元素的时间复杂度为O(1)&#xff0c;但无法通过“下标[ ]”直接访问元素&#xff0c;需要通过从头&#xff08;尾&#…...

51单片机STC8G串口Uart配置

测试环境 单片机型号&#xff1a;STC8G1K08-38I-TSSOP20&#xff0c;其他型号请自行测试&#xff1b; IDE&#xff1a;KEIL C51&#xff1b; 寄存器配置及主要代码 STC8G系列单片机具有4个全双工异步串行通信接口&#xff1b;本文以串口1为例&#xff0c;串口1有4种工作方式…...

uni-app使用movable-area 实现数据的拖拽排序功能

文档地址 template部分 <movable-area :style"getAreaStyle"><movable-view class"table-row" v-for"v,i in move.list":key"v.id":y"v.y"change"handle_moving"direction"vertical"touchst…...

如何设置使PPT的画的图片导出变清晰

PPT画的流程图另存为图片 插入WORD不清晰的解决办法&#xff1a; 第一步&#xff1a;先调整PPT分辨率 根据此链接修改PPT默认的导出dpi 第二步&#xff1a;新建PPT准备 首先看想要保存的图的尺寸&#xff1a;点击图形-格式-长宽 新建一个ppt-设计-幻灯片大小-自定义大小 …...

和鲸科技 CEO 范向伟受邀揭牌启动南京大学 2024 级大学生人工智能素养大赛

2024 年 10 月 26 日&#xff0c;南京大学第十九届读书节在仙林校区图书馆举行开幕仪式。中国科学院院士、南京大学校长谈哲敏&#xff0c;校党委常委、副校长索文斌&#xff0c;原副校长、关工委主任闵铁军出席仪式&#xff0c;南京大学相关学院和职能部处负责人&#xff0c;以…...

NewStarCTF2024-Week4-Web-WP

目录 1、blindsql2 2、chocolate 3、隐藏的密码 4、ezcmsss 题目对勇师傅来说已经是开始上难度了所以这周没有AK 分享下自己做出来的题的解题思路 1、blindsql2 原本是在继续构造新的 payload&#xff0c;也测到了延时 打算去改上周的脚本&#xff0c;结果去跑的时候忘了将…...

Java学习Day56:暴打舔狗!(SpringBoot)

1.springboot简介 核心能力&#xff1a;Spring容器、日志、自动配置AutoCongfiguration、Starters web应用的能力&#xff1a;MVC、嵌入式Web服务器 数据访问(持久化)&#xff1a;关系型数据库、非关系型数据库 强大的整合其他技术的能力 只要是Java中牛逼的技术&#xff0c…...

RSA加密算法实现

Java实现RSA加密算法示例,包括密钥对的生成、加密和解密过程。首先需要导入Java的加密库,这些功能主要通过java.security和javax.crypto包提供。先生成了一个RSA密钥对,包括一个公钥和一个私钥。然后使用公钥加密了一个字符串,并使用私钥解密了加密后的字符串。加密和解密的…...

大数据新视界 -- 大数据大厂之优化大数据计算框架 Tez 的实践指南

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...