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前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
img

结束

一次完整的面试流程就是这样啦,小编综合了腾讯的面试题做了一份前端面试题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、安卓逆向、云计算

  • 26
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值