接口的偶尔捣乱让我事与愿违(axios重复请求问题)

大家好,分享一下最近遇到的一个小问题:关于axios重复请求问题(新人第一篇)

背景:

最近遇到的项目中,遇到了四个selecte选项相互关联下拉数据对应更新的需求

按理说需求简单也应该不会出现什么问题,确实,在开发过程中也没遇到什么问题

但是在测试过程中发现一个bug

因为有一个接口要返回的数据量相比别的接口来说要大,返回时间相比来说很慢,无参数状态下该接口默认全返回,有参数反应的要快些。

复现场景:

当其中一个下拉框选中,另一个下拉数据会跟随对应变化

无选中就是参数为空的,调用的接口返回的是全数据,很慢

选中时候有参数,调用接口接口返回的数据很快

导致 选中-取消-选中 数据开始混乱, 拿到的可能是上一个接口返回的数据(慢返回的数据)

解决问题(AbortController):

注意:开始引入AbortController没有生效,我瞅了一眼版本是真的低,提升了下axios的版本
使用 Axios 您还可以使用 cancel token 取消一个请求,版本相对较低,但是不太推荐

那我们继续说

之前接口调用返回数据慢,可以取消请求,这个就用到了axios里面的AbortController

AbortController是一个控制器对象(DOM API),允许你对尚未完成的异步任务(如fetch请求)进行中止操作。

基本用法

  • 创建一个AbortController实例:

    js 复制代码
    	const controller = new AbortController();
  • 获取与该控制器关联的AbortSignal对象:

    js 复制代码
    	const signal = controller.signal;
  • 使用signal对象发起fetch请求,并将其作为fetch请求的第二个参数(options)的signal属性传递:

    js 复制代码
    	fetch('https://api.example.com/data', { signal })  
    	  .then(response => { /* 处理响应数据 */ })  
    	  .catch(error => {  
    	    if (error.name === 'AbortError') {  
    	      console.log('请求被中止');  
    	    } else {  
    	      console.error('请求失败', error);  
    	    }  
    	  });
  • 在需要取消请求时,调用AbortController实例的abort方法:

    js 复制代码
    	controller.abort();

代码实现:

外部定义

js 复制代码
//正在请求  还没返回的请求
const requestList = new Map();
//请求名单: 为特殊接口添加防重复请求,有些接口不需要这个定义,可能也是我接手项目的原因,老版代码
const whiteRequestList = [
  'v1/manager/2b/operation3/list&get',
  'v1/manager/2b/operation4/list&get',
];

const service = axios.create({
  baseURL: process.env.BASE_URL, // url = base url + request url
  timeout: 5000 // request timeout
})

请求拦截器

js 复制代码
service.interceptors.request.use(
  config => {
    const { url,  method }  = config;
    //map中key值
    let parameter = url + '&' + method;
    //判断缓存map请求里面是否存在当前key值
    let oldControl = requestList.get(parameter);
    //缓存中存在请求key 以及当前key在防重复请求名单里面
    if(!!oldControl && whiteRequestList.includes(parameter)) {
      // 取消请求
      oldControl.abort();
      //删除缓存管理请求
      requestList.delete(parameter)
    }
    //创建请求管理器
    const control = new AbortController();
    //为每个请求配置添加signal属性
    config.signal = control.signal;
    //将每一次的control进行缓存
    requestList.set(parameter,control);
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

响应拦截器

js 复制代码
service.interceptors.response.use(
  response => {
    const res = response.data;
    //响应成功删除缓存地址
    const { url, baseURL, method }  = response.config;
    let parameter = url.replace(baseURL+'/','') + '&' + method;
    requestList.delete(parameter);

    if (res.code !== 200) {
      Message({
        message: res.message || 'Error',
        type: 'error',
        duration: 2 * 1000
      })
      return Promise.reject(new Error(res.message || 'Error'))
    } else {
      return res
    }
  },
  error => {
    return Promise.reject(error)
  }
)

最后成功按住躁动的它

感谢大家的浏览,也希望能够得到大家的肯定和指正

相关推荐
Mr_Xuhhh1 小时前
重生之我在学环境变量
linux·运维·服务器·前端·chrome·算法
永乐春秋2 小时前
WEB攻防-通用漏洞&文件上传&js验证&mime&user.ini&语言特性
前端
鸽鸽程序猿2 小时前
【前端】CSS
前端·css
ggdpzhk2 小时前
VUE:基于MVVN的前端js框架
前端·javascript·vue.js
学不会•4 小时前
css数据不固定情况下,循环加不同背景颜色
前端·javascript·html
活宝小娜6 小时前
vue不刷新浏览器更新页面的方法
前端·javascript·vue.js
程序视点6 小时前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
coldriversnow6 小时前
在Vue中,vue document.onkeydown 无效
前端·javascript·vue.js
我开心就好o6 小时前
uniapp点左上角返回键, 重复来回跳转的问题 解决方案
前端·javascript·uni-app
开心工作室_kaic7 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端