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();
相关推荐
CoderLiu19 分钟前
用这个MCP,只给大模型一个figma链接就能直接导出图片,还能自动压缩上传?
前端·llm·mcp
伍哥的传说21 分钟前
鸿蒙系统(HarmonyOS)应用开发之实现电子签名效果
开发语言·前端·华为·harmonyos·鸿蒙·鸿蒙系统
海的诗篇_1 小时前
前端开发面试题总结-原生小程序部分
前端·javascript·面试·小程序·vue·html
uncleTom6661 小时前
前端地图可视化的新宠儿:Cesium 地图封装实践
前端
lemonzoey1 小时前
无缝集成 gemini-cli 的 vscode 插件:shenma
前端·人工智能
老家的回忆1 小时前
jsPDF和html2canvas生成pdf,组件用的elementplus,亲测30多页,20s实现
前端·vue.js·pdf·html2canvas·jspdf
半点寒12W2 小时前
uniapp全局状态管理实现方案
前端
Vertira2 小时前
pdf 合并 python实现(已解决)
前端·python·pdf
PeterJXL2 小时前
Chrome 下载文件时总是提示“已阻止不安全的下载”的解决方案
前端·chrome·安全
hackchen2 小时前
从0到1解锁Element-Plus组件二次封装El-Dialog动态调用
前端·vue.js·elementui