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

前端如何取消接口调用

🧑‍💻 写在开头
点赞 + 收藏 === 学会🤣🤣🤣

1. xmlHttpRequest是如何取消请求的?

实例化的XMLHttpRequest对象上也有abort方法

const xhr = new XMLHttpRequest();
xhr.addEventListener('load', function(e) {console.log(this.responseText);
});
xhr.open('GET', 'https://jsonplaceholder.typicode.com/todos/1');
xhr.send();
// 返回
{"userId": 1,"id": 1,"title": "delectus aut autem","completed": false
}

如果在send后直接abort取消

// xhr的取消操作:执行过程比较模糊,不知道abort什么时机进行处理
xhr.abort()

如果在定时器中(当定时器的时长那个和接口请求时长差不多)取消请求,会发现资源已经获取到了,但是控制台没有打印
在这里插入图片描述

2. AbortController

const ac = new AbortController();
const { signal } = ac;
const url = "https://jsonplaceholder.typicode.com/todos/1";
​
fetch(url, { signal }).then((res) => res.json()).then((json) => console.log(json));

直接使用abort取消请求

ac.abort()

在这里插入图片描述
这里报错的原因是没有对错误进行捕获

// 修改后的代码
fetch(url, { signal: ac.signal }).then((res) => res.json()).then((json) => console.log(json)).catch(e => console.log(e)) // DOMException: signal is aborted without reason
ac.abort() // abort接受一个入参,会被传递到signal的reason属性中

为什么可以这样取消?

fetch监听signal对象的状态,进而可以终止请求

2.1 如何同时取消多个请求?

const ac = new AbortController();
const { signal } = ac;
const url = "https://jsonplaceholder.typicode.com/todos";
​
const todoRequest = (id, { signal }) => {fetch(`${url}/${id}`, { signal }).then((res) => res.json()).then((json) => console.log(json)).catch((e) => console.log(e)); // DOMException: signal is aborted without reason
};
​
todoRequest(1, { signal });
todoRequest(2, { signal });
todoRequest(3, { signal });
​
ac.abort("cancled");

在这里插入图片描述

2.2 AbortSignal

是一个接口,用于表示一个信号对象,它允许你与正在执行的异步操作通信,以便可以在操作完成之前将其中止。

2.3 AbortSignal的方法

2.3.1 abort

静态方法,用于创建一个已经中止的 AbortSignal 对象。当你调用这个方法时,它会返回一个带有 aborted 状态为 true 的 AbortSignal 实例。

const signalAbout = AbortSignal.abort(); // AbortSignal {aborted: true, reason: DOMException: signal is aborted without reason...}

2.3.2 throwIfAborted 方法

用于在执行代码之前检查 AbortSignal 是否已经被中止。如果 AbortSignal 已经被中止,它会抛出一个 AbortError。这个方法可以帮助开发者在执行特定操作之前确保没有被中止,以避免不必要的处理。

const signalAbout = AbortSignal.abort('abortedReason');
try {signalAbout.throwIfAborted(); // 抛出error: abortedReason
} catch (error) {console.log(error);
}

2.3.3 timeout

用于创建一个在指定时间后自动中止的 AbortSignal 对象。这在需要设置请求超时时非常有用。

// 使用 AbortSignal.timeout 设置 10ms超时
const signalAbout = AbortSignal.timeout(10);
const todoRequest = (id, { signal }) => {fetch(`${url}/${id}`, { signal }).then((res) => res.json()).then((json) => console.log("json: ", json)).catch((e) => console.log("err: ", e)); //DOMException: signal timed out 
};
todoRequest(1, { signal: signalAbout });

在这里插入图片描述

2.3.3.1 添加事件监听 => 从没有终止到被终止

AbortSignal继承自EventTarget,因为 AbortSignal 是用来监听 abort 事件的,而 EventTarget 提供了添加、移除和触发事件监听器的机制。

const signalAbout = AbortSignal.timeout(10);
signalAbout.addEventListener("abort", (e) => {console.log("aborted: ", e);
})
​

e的打印如下:
在这里插入图片描述

3. 实现一个主动取消的promise

const ac = new AbortController();
const { signal } = ac;
​
const cancelablePromise = ({signal}) => new Promise((resolve, reject) => {// 情况1:直接主动取消signal?.throwIfAborted(); // 也可以用reject
​// 情况2:正常处理业务逻辑
​setTimeout(() => {Math.random() > 0.5 ? resolve('data') : reject('fetch error');}, 1000);
​// 情况3:超时 todo?
​// 监听取消signal.addEventListener("abort", () => {reject(signal?.reason);});})
// 发起网络请求
cancelablePromise({signal})
.then(res => console.log('res: ', res))
.catch(err => console.log('err: ', err))
// 情况1 
// ac.abort('用户离开页面了') // err:  用户离开页面了
​
// 情况2 正常请求 err:  fetch error || res:  data

4. 如何使用signal取消事件监听?

当对一个元素添加了多个事件监听,不需要像removeEventListener一样,每个事件都需要取消一次,每次都要写明对应事件的事件句柄

使用signal 只需要取消一次信号,全部事件监听都被取消

const ac = new AbortController();
const { signal } = ac;
const eleA = document.querySelector('#a');
const eleB = document.querySelector('#b');
​
function aEleHandler () {}; // 事件
eleA.addEventListener('click', aEleHandler, {signal}); // 无论绑定多少个事件,都只需要一个signal
​
eleB.addEventListener('click', () => {ac.abort(); // 只需要取消一次
})

5. 请求多个接口进行数据组装的场景

当网速不好的时候,如何取消这种不断进行的网络请求?

const ac = new AbortController();
const { signal } = ac;
const fetchAndRenderAction = (signal) => {requestData(signal); // 多个串行或者并行的接口drawAndRender(signal); // 异步渲染
}
​
try{fetchAndRenderAction({signal})
}catch{// dosomething...
}

6. 总结

对于用户主动离开页面,或者用户的网络很卡的时候(预期返回顺序是:接口1 => 接口2;但是接口1返回太慢,导致顺序混乱。)这就需要手动终止请求。构造函数AbortController的实例信号量signal(可以作为ref存储起来),signal作为fetch的参数,在每次请求的时候,可以手动调用abort方法,取消上一次的请求。

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。
在这里插入图片描述

相关文章:

前端如何取消接口调用

🧑‍💻 写在开头 点赞 收藏 学会🤣🤣🤣 1. xmlHttpRequest是如何取消请求的? 实例化的XMLHttpRequest对象上也有abort方法 const xhr new XMLHttpRequest(); xhr.addEventListener(load, function(e)…...

k8s 容器环境下的镜像如何转换为docker 使用

在无法连接registry 的环境中,想要把 crictl 中的镜像给docker 使用,应该怎么处理? 其实容器镜像是通用的,crictl 和ctr 以及docker 镜像是可以互相使用的,因为docker 在1.10版本之后遵从了OCI。所以crictl 环境下的镜…...

FreeRTOS 队列

队列是一种任务到任务、任务到中断、中断到任务数据交流的一种机制。在队列中可以存 储数量有限、大小固定的多个数据,队列中的每一个数据叫做队列项目,队列能够存储队列项 目的最大数量称为队列的长度,在创建队列的时候,就需要指…...

如何识别图片文字转化为文本?5个软件帮助你快速提取图片文字

如何识别图片文字转化为文本?5个软件帮助你快速提取图片文字 将图片中的文字提取为文本是一项非常有用的技能,特别是当你需要处理大量扫描文档、截图或其他图片时。以下是五款能够帮助你快速提取图片文字的软件: 迅捷文字识别 这是一款非…...

Flink SQL kafka连接器

版本说明 Flink和kafka的版本号有一定的匹配关系,操作成功的版本: Flink1.17.1kafka_2.12-3.3.1 添加kafka连接器依赖 将flink-sql-connector-kafka-1.17.1.jar上传到flink的lib目录下 下载flink-sql-connector-kafka连接器jar包 https://mvnreposi…...

glm-4 联网搜索 api 测试

今天测试了一下 glm-4 的联网搜索 web_search tool 调用,发现了 web_search 的网页检索返回结果中几个比较诡异的事情,特此记录: 有些检索结果没有 icon、link、media 字段,但从内容上看确实是联网搜索出来的结果,不知…...

Java毕业设计 基于SSM vue图书管理系统小程序 微信小程序

Java毕业设计 基于SSM vue图书管理系统小程序 微信小程序 SSM 图书管理系统小程序 功能介绍 用户 登录 注册 首页 图片轮播 图书信息推荐 图书详情 赞 踩 评论 收藏 系统公告 公告详情 用户信息修改 我的待还 图书归还 催还提醒 我的收藏管理 意见反馈 管理员 登录 个人中心…...

bert训练的一些技巧(rand() < self.skipgram_prb)

rand() < self.skip_gram_prb) 是一个条件表达式&#xff0c;用来判断是否进行skip-gram掩码操作。这种掩码操作通常用于自然语言处理中的数据增强&#xff0c;通过概率决定是否应用skip-gram掩码。下面是对这个表达式的详细解释&#xff1a; 解释 rand(): rand() 是一个随…...

pandas修改时间索引报错处理

import pandas as pd import numpy as np import osdfpd.DataFrame(index[a,b,c],data{序列:[1,2,3]}) df.rename(index{a:a1},inplaceTrue) print(df) print(df.index.dtype)df1pd.DataFrame(index[2024-01-01,2024-01-02,2024-01-03],data{序列:[1,2,3]}) df1.rename(index{2…...

Nginx Bla~Bla~

root 和 alias指令都用于指定服务器上的文件系统路径&#xff0c;但它们在用法和行为上有一些不同 root指令通常用于在Nginx配置中定义一个目录&#xff0c;该目录将作为请求的根目录。 server { location /static/ {root /var/www; 请求 /static/index.html 将映射到 /v…...

java awt和swing介绍

Java AWT&#xff08;Abstract Window Toolkit&#xff09;和 Swing 是用于创建图形用户界面&#xff08;GUI&#xff09;的 Java API。 AWT AWT 是 Java 最初的平台依赖的窗口图形界面工具包&#xff0c;它提供了一组基本的 GUI 组件、窗口管理、事件处理等。AWT 组件是重量…...

奇怪的错误记录

https://github.com/meta-llama/llama3/issues/80 读模型没问题&#xff0c;推理时出现&#xff1a; RuntimeError: “triu_tril_cuda_template” not implemented for ‘BFloat16’ ———————————————— 事发原因 我尝试了解transformers的AutoProcessor时&a…...

来啦,经典传说大变身牛郎织女后代逗趣日常

《落凡尘&#xff1a;星宿大冒险》来啦&#xff01; 经典传说大变身&#xff0c;牛郎织女后代金风&#xff0c; 上演一出“星际小侦探”的逗趣日常&#xff01; 想象一下&#xff0c;二十八星宿那些傲娇的星星们&#xff0c; 居然能“离家出走”&#xff0c;还差点把天给掀了…...

【uniapp-ios】App端与webview端相互通信的方法以及注意事项

前言 在开发中&#xff0c;使用uniapp开发的项目开发效率是极高的&#xff0c;使用一套代码就能够同时在多端上线&#xff0c;像笔者之前写过的使用Flutter端和webview端之间的相互通信方法和问题&#xff0c;这种方式本质上实际上是h5和h5之间的通信&#xff0c;网上有非常多…...

Qt常用基础控件总结—表格控件(QTableWidget类)

表格控件QTableWidget 表格控件最上面一排是只读的水平表头,最左边一列是只读的垂直表头。表头又可以细分为多个分段(section),水平表头的分段就是表格各个列的列首,垂直表头 分段就是表格各个行的行首。表格控件的实体区域是按行、列排布的单元格,单元格内容一般用 QTa…...

笔记:Entity Framework Core 数据库迁移add-migration

一、目的&#xff1a; 数据库迁移是一种管理数据库架构变化的技术&#xff0c;它允许开发者在应用程序的生命周期中安全地更新数据库架构&#xff0c;而不会丢失数据或破坏现有的数据库结构。在Entity Framework Core&#xff08;EF Core&#xff09;中&#xff0c;数据库迁移特…...

准备工作+1、请求和响应+2、模型和管理站点

Django快速入门——创建一个基本的投票应用程序 准备工作1、创建虚拟环境2、安装django 1、请求和响应&#xff08;1&#xff09;创建项目&#xff08;2&#xff09;用于开发的简易服务器&#xff08;3&#xff09;创建投票应用&#xff08;4&#xff09;编写第一个视图1、编写…...

js 格式化时间

方法一&#xff1a;使用toLocaleString或toLocaleDateString/toLocaleTimeString Date对象提供了toLocaleString()、toLocaleDateString()和toLocaleTimeString()方法&#xff0c;这些方法允许你根据本地时间格式来显示日期和时间。虽然它们不直接提供高度自定义的格式选项&am…...

python 缩放照片

pip install Pillow from PIL import Image 打开一个图片文件 img Image.open(r"C:\Users\Administrator\Desktop\我的证件\证件照.jpg") 设定新的尺寸 new_size (480, 640) 缩放图片 resized_img img.resize(new_size) 显示缩放后的图片 resized_img.sh…...

【C语言】指针(1):入门理解(课堂随笔)

目录 一、内存和地址 二、指针变量和地址 三、指针变量类型的意义 一、内存和地址 只要讲指针就离不开内存 因为指针就是访问内存的 计算上CPU&#xff08;中央处理器&#xff09;在处理数据的时候&#xff0c;需要的数据是在内存中读取的&#xff0c;处理后的数 据也会放…...

手把手教你用Vivado仿真FPGA乘法器:从Testbench编写到波形调试全流程指南

FPGA乘法器仿真实战&#xff1a;Vivado Testbench编写与波形调试全解析 第一次接触FPGA乘法器仿真时&#xff0c;我盯着屏幕上那些跳动的波形线&#xff0c;完全不知道它们在传达什么信息。直到后来通过反复实践&#xff0c;才真正理解如何通过仿真验证一个乘法器模块的正确性。…...

2025届毕业生推荐的五大AI辅助写作平台横评

Ai论文网站排名&#xff08;开题报告、文献综述、降aigc率、降重综合对比&#xff09; TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 把人工智能生成内容的检测概率给降低&#xff0c;得从文本特征方面着手去进行系统性的优化。…...

谷歌发布Gemma 4模型,为低功耗设备带来复杂推理能力

谷歌发布了其最先进的开放权重人工智能模型家族Gemma 4&#xff0c;这标志着开放权重AI模型领域的重大进步。技术架构与性能突破Gemma 4基于与Gemini 3相同的架构基础构建&#xff0c;专门设计用于处理复杂推理任务&#xff0c;并支持在工作站和智能手机等低功耗设备上本地运行…...

**AI仿真人剧厂家2025推荐,专业定制与沉浸式体验的行业标杆**据中国信通院2025年人工智能数字内容产业白皮书显示,2025年国内AI仿真人剧市场规模预计突破120亿元,年增长率高达65%。

AI仿真人剧厂家2025推荐&#xff0c;专业定制与沉浸式体验的行业标杆据中国信通院《2025年人工智能数字内容产业白皮书》显示&#xff0c;2025年国内AI仿真人剧市场规模预计突破120亿元&#xff0c;年增长率高达65%。然而&#xff0c;行业调研数据显示&#xff0c;超过70%的内容…...

为什么你的Python AOT项目预算超支300%?2026成本控制策略失效的4个关键信号(附审计检查表)

第一章&#xff1a;Python原生AOT编译成本失控的根源诊断Python 原生 AOT&#xff08;Ahead-of-Time&#xff09;编译正面临严峻的工程现实&#xff1a;编译时间激增、内存占用爆炸、二进制体积膨胀&#xff0c;且生成代码性能常低于预期。这一“成本失控”现象并非偶然&#x…...

高可用外卖返利 CPS 平台:Java 后端异步回调处理机制深度解析

高可用外卖返利 CPS 平台&#xff1a;Java 后端异步回调处理机制深度解析 在构建外卖返利&#xff08;CPS&#xff09;系统时&#xff0c;异步回调&#xff08;Callback&#xff09;机制是连接用户授权、订单同步与佣金结算的神经中枢。美团、饿了么等平台的用户授权与订单状态…...

安规标准考核题库-1(IEC 62477-1:2012+AMD1:2022 )

本题库严格对标 IEC 62477-1:2012《电力电子变换器系统和设备安全要求 第 1 部分&#xff1a;总则》AMD1:2022 修订版&#xff0c;贴合储能双向 PCS 的设计、测试、认证全流程场景&#xff0c;分为判断题、单选题、多选题三类&#xff0c;所有题目均附标准条款依据与详细解答。…...

基于粒子群算法(PSO)的宽带消色差超透镜Matlab核心程序探秘

基于粒子群算法PSO宽带消色差超透镜matlab核心程序有注释便于理解代码的含义&#xff0c;包含FDTD仿真&#xff0c;文章复现案例讲解&#xff0c;适合学习几何相位和传输相位&#xff0c;消色差效果很好可以对代码进行优化在光学领域&#xff0c;宽带消色差超透镜是一个热门的研…...

Notepad--:当文本编辑遇到真正的跨平台解决方案

Notepad--&#xff1a;当文本编辑遇到真正的跨平台解决方案 【免费下载链接】notepad-- 一个支持windows/linux/mac的文本编辑器&#xff0c;目标是做中国人自己的编辑器&#xff0c;来自中国。 项目地址: https://gitcode.com/GitHub_Trending/no/notepad-- 你是否曾因…...

告别重复输入:快马助你打造高效openclaw命令管理工具

最近在团队协作中频繁使用openclaw工具时&#xff0c;发现每次手动输入冗长的命令参数特别容易出错&#xff0c;尤其是当需要切换不同环境配置时&#xff0c;常常因为输错一个参数导致整个流程卡住。于是决定用Python开发一个小工具来提升操作效率&#xff0c;顺便把实现过程记…...