axios取消重复请求

axios取消重复请求

应用场景:

一次操作触发多个请求,请求响应顺序错乱将会影响展示的结果

实现思路:

通过 Axios 的请求拦截器和响应拦截器来实现取消重复请求的功能。每当一个新的请求被发起时,都会检查是否存在相同的请求,如果存在,则取消之前的请求。使用axios.CancelToken 来创建取消令牌,并将其附加到请求配置中。当请求完成或被取消时,会从 pendingRequests 中移除对应的请求和取消函数。实际情况中并不是所有接口都需要进行取消操作,所以在请求配置中添加了一个 allowCancel标记,在请求拦截器中,如果检测到该标记存在,则进行取消操作 ,对于其他未标记允许取消请求的接口,直接发送请求,不进行取消操作。

代码

axios 封装

复制代码
import axios from 'axios';

const http = axios.create({
  timeout: 20000,
  withCredentials: true,
  headers: { 'X-Requested-With': 'XMLHttpRequest' },
})

// 用于存储每个请求的取消函数
const pendingRequests = new Map();

// 添加请求拦截器
http.interceptors.request.use(config => {
  // 如果请求配置中没有标记允许取消请求,则直接发送请求,不进行取消操作
  if (!config.allowCancel) {
    return config;
  }

  // 在发送请求之前,检查是否存在相同的请求
  const requestId = JSON.stringify(config);
  if (pendingRequests.has(requestId)) {
    // 如果存在相同的请求,则取消之前的请求
    pendingRequests.get(requestId).cancel();
  }
  
  // 创建新的取消令牌
  const cancelTokenSource = axios.CancelToken.source();
  config.cancelToken = cancelTokenSource.token;

  // 存储新的请求和取消函数
  pendingRequests.set(requestId, cancelTokenSource);
  
  return config;
}, error => {
  return Promise.reject(error);
});

// 添加响应拦截器
http.interceptors.response.use(response => {
  // 请求完成后,从 pendingRequests 中移除对应的请求和取消函数
  const requestId = JSON.stringify(response.config);
  pendingRequests.delete(requestId);
  return response;
}, error => {
  // 如果请求被取消,则直接返回空响应
  if (axios.isCancel(error)) {
  	// 自定义返回内容
    return Promise.resolve({
      data: null,
      status: -1,
      statusText: 'Request canceled'
    });
  }
  
  return Promise.reject(error);
});

使用示例

复制代码
// 示例函数,发起 GET 请求
const fetchData = async  () => {
  try {
    // 允许取消请求的接口
    const response1 = await api.get('/getData1', { allowCancel: true });
    console.log(response1.data);
    
    // 不允许取消请求的接口
    const response2 = await api.get('/getData2');
    console.log(response2.data);
  } catch (error) {
    console.error('Error:', error);
  }
}

// 调用示例函数
fetchData();
相关推荐
codeGoogle13 小时前
自研 IM 还是选择第三方 SDK?企业开发者应该如何权衡?
前端·后端·程序员
用户9385156350714 小时前
React Context 与自定义 Hook 从底层到实践:「跨层级通信 + 副作用封装」全解析
前端·javascript·react.js
滴滴答答哒15 小时前
VUE3+element-plus MultiSelect 多选下拉组件
前端·javascript·vue.js
其美杰布-富贵-李15 小时前
04 watch 与 Vue 响应式数据流
前端·javascript·vue.js
赵大仁16 小时前
生成式 UI 实战:用 JSON Schema + React 动态渲染 AI 界面
前端·ai·react·next.js·前端架构·生成式ui
kyriewen17 小时前
我排查了一个React内存泄漏——罪魁祸首是这3个被忽略的清理函数
前端·javascript·面试
IT_陈寒18 小时前
我又被JavaScript的隐式类型转换坑了
前端·人工智能·后端
其美杰布-富贵-李18 小时前
03 ref、reactive 与 computed 响应式数据
前端·javascript·vue.js
OpenTiny社区18 小时前
GenUI SDK v1.3.0 发布|多框架兼容,一键换物料,渲染器 & 演练场全面增强!
前端·ai编程
用户9385156350718 小时前
useRef + Web Worker 实战:React 如何优雅地拥抱多线程
前端·javascript·react.js