axios取消请求CancelToken的原理解析及用法示例

2024-08-27 13:36

本文主要是介绍axios取消请求CancelToken的原理解析及用法示例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

      • 一、axios的实例与请求流程
      • 二、CancelToken 的作用
      • 三、CancelToken 的实现原理
      • 四、取消请求的流程
      • 五、CancelToken用法
      • 六、利用拦截器取消请求
        • 1、axios请求拦截器
        • 2、axios响应拦截器
        • 3、利用路由导航守卫取消请求

一、axios的实例与请求流程

下图是axios实例属性的简图。

在这里插入图片描述

下图是axios的请求流程

在这里插入图片描述

axios的实例上,其实主要就这三个东西:

  • config:配置,比如url、method、params、headers等等
  • interceptors :拦截器,分为请求拦截器和返回拦截器。
  • request:调用xhr或者http请求的方法,参数就是config

二、CancelToken 的作用

Axios 是一个基于 Promise 的 HTTP 客户端,用于在浏览器和 Node.js 中发起 HTTP 请求。除了强大的功能和丰富的配置选项,Axios 还提供了一个实用的特性——CancelToken,它允许我们取消一个或多个正在进行的请求。

在网络应用中,我们经常需要处理一些可能需要取消的请求,比如用户在加载数据时跳转到了其他页面,或者在表单提交前用户点击了取消按钮。在这些场景下,如果能够取消请求,就能避免不必要的资源消耗和更好的用户体验。

三、CancelToken 的实现原理

CancelToken 的工作原理依赖于 Promise 的链式调用和 throw 语句。在 Axios 发起请求时,会检查请求的 cancelToken 属性,如果存在,就将其添加到当前请求的 cancelToken 列表中。

当调用 cancel 方法时,CancelToken 会抛出一个带有特定 message 的 Cancel 对象。这个对象会被 Promise 的 catch 方法捕获,从而触发请求的取消逻辑。

四、取消请求的流程

CancelToken的静态方法CancelToken.source返回了两个东西:分别是token和cancel方法。

在这里插入图片描述

下图是取消请求的流程

在这里插入图片描述

可以看到,流程里,axios分别在请求前、请求中、请求后进行了是否取消的判断。

这也就意味着,当我们在请求拦截器中调用cancel方法,axios会识别到,抛出异常。

五、CancelToken用法

先引用axios.CancelToken,然后调用source()方法,会产生一个token和cancel

const CancelToken = axios.CancelToken;
const source = CancelToken.source();// get请求示例
axios.get('/user/12345', {cancelToken: source.token
}).catch((thrown)=> {if (axios.isCancel(thrown)) {console.log('Request canceled', thrown.message);} else {// 处理错误}
});// post请求示例
axios.post('/user/12345', {name: 'new name'}, {cancelToken: source.token});// 取消请求(message 参数是可选的)
source.cancel('不想请求了');
  • get请求的时候,cancelToken是放在第二个参数里;
  • post的时候,cancelToken是放在第三个参数里。

六、利用拦截器取消请求

先封装一下方法

// 全局变量对象,专门存放所有请求的cancel方法
window.pendingRequest = new Map()// 生成request的唯一的标识
const generateRequestKey = (config = {}) => {// 通过url,method,params,data生成唯一key,用于判断是否重复请求// params为get请求参数,data为post请求参数const {url,method,params,data} = configif (method == 'get') {return [url, method, qs.stringify(params)].join('&')}return [url, method, qs.stringify(data)].join('&')
}// 将重复请求添加到pendingRequest中
const addPendingRequest = (config) => {const key = generateRequestKey(config)if (!pendingRequest.has(key)) {config.cancelToken = new axios.CancelToken(cancel => {pendingRequest.set(key, cancel)})}
}// 取消重复请求
const cancelRepeatRequest = (config) => {const key = generateRequestKey(config)if (pendingRequest.has(key)) {const cancelToken = pendingRequest.get(key)cancelToken(key) // 取消之前发送的请求pendingRequest.delete(key) // 请求对象中删除requestKey}
}
1、axios请求拦截器

在发送请求之前,为每个请求生成一个唯一的标识,这个标识可以根据请求的URL、方法以及所传递的参数等信息生成。

通过使用Axios的请求拦截器,你可以在请求发送前进行检查,如果发现有一个相同标识的请求已经在进行中,就可以使用CancelToken取消前一个请求,或者跳过当前请求。

// 创建axios实例
const httpService = axios.create({});// request拦截器
httpService.interceptors.request.use(config => {// 取消重复请求cancelRepeatRequest(config)// 添加请求到队列addPendingRequest(config)return config;},error => {return Promise.reject(error);}
)
2、axios响应拦截器

响应拦截器可以用来清理已完成或已取消的请求的记录,确保请求映射表只保留活跃的请求。这个机制使得在实际应用中管理和取消重复的请求变得容易。

httpService.interceptors.response.use(response => {// 取消请求队列中该请求cancelRepeatRequest(response .config);if (response.status == 200) {return response;} else {return Promise.reject(response);}},// 处理处理error => {// 取消请求队列中该请求cancelRepeatRequest(error.config || {})return Promise.reject(error);}
)

在这里插入图片描述
在这里插入图片描述

这里我同时发送了3次重复的history请求,过滤取消了2次,成功发送了1次。

3、利用路由导航守卫取消请求

当路由切换的时候,在路由钩子里遍历这个数组,调用所有的cancel方法,将上一个页面还未完的请求取消,这样就可以加快页面的加载,避免不必要的等待。

router.beforeEach((to, from, next) => {if(pendingRequest){pendingRequest.forEach((cancel) => {cancel();});pendingRequest = new Map();}next();
})  

当路由切换页面的时候,遍历全局数组,将上一个页面的所有请求cancel掉。

在这里插入图片描述

图中history接口是上个页面的,还没返回结果,切换路由后,请求被取消。

这篇关于axios取消请求CancelToken的原理解析及用法示例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1111819

相关文章

MySQL字符串转数值的方法全解析

《MySQL字符串转数值的方法全解析》在MySQL开发中,字符串与数值的转换是高频操作,本文从隐式转换原理、显式转换方法、典型场景案例、风险防控四个维度系统梳理,助您精准掌握这一核心技能,需要的朋友可... 目录一、隐式转换:自动但需警惕的&ld编程quo;双刃剑”二、显式转换:三大核心方法详解三、典型场景

MySQL中between and的基本用法、范围查询示例详解

《MySQL中betweenand的基本用法、范围查询示例详解》BETWEENAND操作符在MySQL中用于选择在两个值之间的数据,包括边界值,它支持数值和日期类型,示例展示了如何使用BETWEEN... 目录一、between and语法二、使用示例2.1、betwphpeen and数值查询2.2、be

python中的flask_sqlalchemy的使用及示例详解

《python中的flask_sqlalchemy的使用及示例详解》文章主要介绍了在使用SQLAlchemy创建模型实例时,通过元类动态创建实例的方式,并说明了如何在实例化时执行__init__方法,... 目录@orm.reconstructorSQLAlchemy的回滚关联其他模型数据库基本操作将数据添

Java数组动态扩容的实现示例

《Java数组动态扩容的实现示例》本文主要介绍了Java数组动态扩容的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1 问题2 方法3 结语1 问题实现动态的给数组添加元素效果,实现对数组扩容,原始数组使用静态分配

JAVA项目swing转javafx语法规则以及示例代码

《JAVA项目swing转javafx语法规则以及示例代码》:本文主要介绍JAVA项目swing转javafx语法规则以及示例代码的相关资料,文中详细讲解了主类继承、窗口创建、布局管理、控件替换、... 目录最常用的“一行换一行”速查表(直接全局替换)实际转换示例(JFramejs → JavaFX)迁移建

Spring Boot Interceptor的原理、配置、顺序控制及与Filter的关键区别对比分析

《SpringBootInterceptor的原理、配置、顺序控制及与Filter的关键区别对比分析》本文主要介绍了SpringBoot中的拦截器(Interceptor)及其与过滤器(Filt... 目录前言一、核心功能二、拦截器的实现2.1 定义自定义拦截器2.2 注册拦截器三、多拦截器的执行顺序四、过

MyBatis中的两种参数传递类型详解(示例代码)

《MyBatis中的两种参数传递类型详解(示例代码)》文章介绍了MyBatis中传递多个参数的两种方式,使用Map和使用@Param注解或封装POJO,Map方式适用于动态、不固定的参数,但可读性和安... 目录✅ android方式一:使用Map<String, Object>✅ 方式二:使用@Param

SpringBoot实现图形验证码的示例代码

《SpringBoot实现图形验证码的示例代码》验证码的实现方式有很多,可以由前端实现,也可以由后端进行实现,也有很多的插件和工具包可以使用,在这里,我们使用Hutool提供的小工具实现,本文介绍Sp... 目录项目创建前端代码实现约定前后端交互接口需求分析接口定义Hutool工具实现服务器端代码引入依赖获

C#中DateTime的格式符的实现示例

《C#中DateTime的格式符的实现示例》本文介绍了C#中DateTime格式符的使用方法,分为预定义格式和自定义格式两类,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值... 目录DateTime的格式符1.核心概念2.预定义格式(快捷方案,直接复用)3.自定义格式(灵活可控

MyBatisPlus乐观锁和悲观锁的实现示例

《MyBatisPlus乐观锁和悲观锁的实现示例》本文主要介绍了MyBatisPlus乐观锁和悲观锁,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小... 目录1.场景2.乐观锁和悲观锁3.乐观锁实现4.悲观锁1.场景一件商品,成本价是80元,售价是10