Vue 取消 axios 重复请求,将性能优化进行到底(你知道发出去的请求还能这么取消吗?
优化版
<el-button type=“plain” @click=“search”>搜索
此时,如果我们连续多次点击按钮,结果如下
在上一次请求未响应完成,发起重复请求,则将上一次请求取消,以达到优化效果。
2、CancelToken
构造函数
我们也可以通过传递一个 executor 函数到 CancelToken
的构造函数来创建 cancel token
let CancelToken = axios.CancelToken;
let cancel;
axios.get(‘/user/12345’, {
cancelToken: new CancelToken(function executor© {
// executor 函数接收一个 cancel 函数作为参数
cancel = c;
})
});
// 取消请求
cancel();
实例
如下方式也能达到取消重复请求的效果
<el-button type=“plain” @click=“search”>搜索
我们知道,发出去的请求(处于pending阶段)可以使用以上两种方式进行取消或中断。那么,在真实的项目中,我们可能需要为全部的请求进行此项优化(取消重复请求),那又该如何去实现?
全局请求优化
这里会涉及到一个问题,我们为全局的请求进行此项优化时,如何判断是否为重复的请求呢?如我在发送1请求,紧接着去发送2请求,此时不算是重复请求,不需要取消;而当发送1请求,1请求还未响应完成时紧接着再去发送1请求,此时判定为重复请求,则执行取消上一次重复请求的操作。
1、如何判断重复请求?
当请求方式、请求 URL 和请求参数都一样时,我们就可以认为请求是一样的。因此在每次发起请求时,我们就可以根据当前请求的请求方式、请求 URL 地址和请求参数来生成一个唯一的 key,同时为每个请求创建一个专属的 CancelToken,然后把 key 和 cancel 函数以键值对的形式保存到 Map 对象中,使用 Map 的好处是可以快速的判断是否有重复的请求
let pendingRequest = new Map();
// 生成唯一的key
let requestKey = [method, url, JSON.stringify(params), JSON.stringify(data)].join(‘&’);
let cancelToken = new CancelToken(function executor(cancel) {
if(!pendingRequest.has(requestKey)){
// 如果发送的请求不存在,则进行保存
pendingRequest.set(requestKey, cancel); // 保存cancel函数,以便后续执行取消请求操作
}
})
当出现重复请求的时候,我们就可以使用 cancel 函数来取消前面已经发出的请求,在取消请求之后,我们还需要把取消的请求从 pendingRequest
中移除。
2、如何取消重复请求?
因为我们需要为全局请求进行此优化,此时可以在拦截器上添加相关配置。
在配置请求拦截器和响应拦截器前,我们先定义3个功能辅助函数。
getRequestKey
:用于根据当前请求的信息,生成唯一的请求 key:
// 函数返回唯一的请求key
function getRequestKey(config) {
let { method, url, params, data } = config;
return [method, url, JSON.stringify(params), JSON.stringify(data)].join(“&”);
}
addPendingRequest
:用于把当前请求信息添加到pendingRequest对象中:
let pendingRequest = new Map();
function addPendingRequest(config) {
let requestKey = getRequestKey(config);
config.cancelToken = config.cancelToken || new axios.CancelToken((cancel) => {
if (!pendingRequest.has(requestKey)) {
pendingRequest.set(requestKey, cancel);
}
});
}
removePendingRequest
:检查是否存在重复请求,若存在则取消已发的请求:
function removePendingRequest(config) {
let requestKey = getRequestKey(config);
if (pendingRequest.has(requestKey)) {
// 如果是重复的请求,则执行对应的cancel函数
let cancel = pendingRequest.get(requestKey);
cancel(requestKey);
// 将前一次重复的请求移除
pendingRequest.delete(requestKey);
}
}
3、配置拦截器
请求拦截器
axios.interceptors.request.use(
function (config) {
// 检查是否存在重复请求,若存在则取消已发的请求
removePendingRequest(config);
// 把当前请求信息添加到pendingRequest对象中
addPendingRequest(config);
return config;
},
function (error) => {
return Promise.reject(error);
}
);
响应拦截器
axios.interceptors.response.use(
function (response) => {
// 从pendingRequest对象中移除请求
removePendingRequest(response.config);
return response;
},
function (error) => {
// 从pendingRequest对象中移除请求
removePendingRequest(error.config || {});
if (axios.isCancel(error)) {
console.log(“已取消的重复请求:” + error.message);
} else {
// 添加异常处理
}
return Promise.reject(error);
}
);
完整实例
import axios from “axios”;
// 函数返回唯一的请求key
function getRequestKey(config) {
let { method, url, params, data } = config;
return [method, url, JSON.stringify(params), JSON.stringify(data)].join(“&”);
}
// 添加请求信息
let pendingRequest = new Map();
function addPendingRequest(config) {
let requestKey = getRequestKey(config);
config.cancelToken = config.cancelToken || new axios.CancelToken((cancel) => {
if (!pendingRequest.has(requestKey)) {
pendingRequest.set(requestKey, cancel);
}
});
}
// 取消重复请求,移除重复请求信息
function removePendingRequest(config) {
let requestKey = getRequestKey(config);
if (pendingRequest.has(requestKey)) {
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
结束
一次完整的面试流程就是这样啦,小编综合了腾讯的面试题做了一份前端面试题PDF文档,里面有面试题的详细解析,分享给小伙伴们,有没有需要的小伙伴们都去领取!
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
ToO-1712193693244)]
结束
一次完整的面试流程就是这样啦,小编综合了腾讯的面试题做了一份前端面试题PDF文档,里面有面试题的详细解析,分享给小伙伴们,有没有需要的小伙伴们都去领取!
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
更多推荐
所有评论(0)