axios取消重复请求

说明:在实际使用中,重复的请求往往导致数据结果显示错乱,例如,重复请求2次,表格分页展示的是第一次请求的数据。这种情况希望在请求第二次前取消第一次的请求

1、取消重复请求示例

<template>

<div>news组件</div>

<el-button type="primary" @click="handleClick">点击</el-button>

</template>

<script lang="ts" setup>

import axios from "axios";

let url = 'API地址'

let control

const handleClick = () => {

if(control) {

control.abort('取消之前的请求')

}

control = new AbortController()

axios.post(url, {

参数1: "123540",

参数2: "2025-04-01",

},{

signal: control.signal // 传递 signal,必须要的

}).then(res => {

console.log(res)

control = null

}).catch(err=>{

if(axios.isCancel(err)){

console.log(err.message+'取消请求')

}else{

console.log(err + '其他错误')}

})

}

</script>

2、封装axios,支持参数自定义取消请求

2.1封装成request.ts
复制代码
import axios from 'axios';
import type { AxiosRequestConfig } from 'axios';

// 存储pending请求
const pendingMap = new Map<string, AbortController>()

// 生成请求key
const generateReqKey = (config: AxiosRequestConfig) => {
  const { url, method, params, data } = config
  return [url, method, JSON.stringify(params), JSON.stringify(data)].join('&')
}

// 取消重复请求
const removePendingRequest = (config: AxiosRequestConfig, cancel: boolean = false) => {
  const requestKey = generateReqKey(config)
  if (pendingMap.has(requestKey)) {
    if (cancel) {
      pendingMap.get(requestKey)?.abort('取消重复请求')
    }
    pendingMap.delete(requestKey)
  }
}

// 创建axios实例
const instance = axios.create({
  baseURL: 'https://example.cn',
  timeout: 10000
})

// 请求拦截器
instance.interceptors.request.use(config => {
  // 由于 config 上不存在 cancelDuplicate 属性,这里使用可选链操作符来避免报错
  // 由于 AxiosRequestConfig 上不存在 cancelDuplicate 属性,我们可以使用类型断言来绕过类型检查
  const cancelDuplicate = (config as AxiosRequestConfig & { cancelDuplicate?: boolean })?.cancelDuplicate;
  if (cancelDuplicate === true) { // 默认不开启开启取消重复请求
    removePendingRequest(config, true)
    const controller = new AbortController()
    config.signal = controller.signal
    pendingMap.set(generateReqKey(config), controller)
  }
  return config
})

// 响应拦截器
instance.interceptors.response.use(response => {
  const { config } = response
  removePendingRequest(config)
  return response.data
}, error => {
  if (axios.isCancel(error)) {
    console.log(`请求被取消: ${error.message}`)
    return Promise.reject(error)
  }
  return Promise.reject(error)
})

export default instance
2.2 页面使用

只需要传入参数cancelDuplicate: true 就可以取消请求

复制代码
<template>
  <div>
    <el-button type="primary" @click="handleClick">取消重复请求</el-button>
  </div>
</template>
<script lang="ts" setup>
import request from '@/utils/request'

const handleClick = () => {
  request.post('/aisleep-api/ammsreport/app/report/explain', {
    uid: "123540",
    day: "2025-04-01"
  }, {
    headers: {
      "Token": "eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyX2lkIjoxMjM1NDAsInVzZXJfa2V5IjoiYzgxZmJmNmYtMTI4Mi00ZWQyLTlhZGMtM2ZiN2EyMjVjZDFkIiwidXNlcm5hbWUiOiIxMzY3MDAzNjk0NiJ9.teA6bo8aIJhmrTiMdwSVpYcUS_qZrxKk29qlnYz0Zzb184FrbQJyQZhWybDk4vWLKLzmomDA53Wv_INShfXJSA"
    },
    cancelDuplicate: true // 开启取消重复请求
  }).then(res => {
    console.log(res)
  }).catch(err => {
  })
}
const getData = async () => {
  request.post('/aisleep-api/ammsreport/app/report/explain', {
    uid: "123540",
    day: "2025-04-01"
  }, {
    headers: {
      "Token": "eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyX2lkIjoxMjM1NDAsInVzZXJfa2V5IjoiYzgxZmJmNmYtMTI4Mi00ZWQyLTlhZGMtM2ZiN2EyMjVjZDFkIiwidXNlcm5hbWUiOiIxMzY3MDAzNjk0NiJ9.teA6bo8aIJhmrTiMdwSVpYcUS_qZrxKk29qlnYz0Zzb184FrbQJyQZhWybDk4vWLKLzmomDA53Wv_INShfXJSA"
    },
  }).then(res => {
    console.log(res)
  }).catch(err => {
  })
}
onMounted(() => {
  getData()
  setTimeout(() => {
    getData()
  }, 100)
})
</script>
3.3 运行结果
相关推荐
C++ 老炮儿的技术栈12 分钟前
有符号变量与无符号变量的区别
服务器·开发语言·前端·数据结构·c++·算法·c
aixingpan22 分钟前
aixingpan.cn API开发文档:api_docs_bichart_natalvssecondary2接口指南
前端·php
MZ_ZXD00132 分钟前
【关注可白嫖源码】--课程设计--毕业设计-- 29210 Vue.js 3+Springboot中药材基本信息与图片查询系统
javascript·spring boot·课程设计·毕设·大作业·程序开发·毕设代做
liangshanbo121535 分钟前
Webpack Tree Shaking 面试题整理
前端·webpack·node.js
斯内普吖39 分钟前
(开源)水果蔬菜商城实战指南 基于 Java + SSM + Vue + MySQL
java·vue.js·mysql·开源
Ai-_Man1 小时前
您您这可以把Google AI Studio的多个会话比如说。左侧的多个会话一次性导出吗?不是单条会话里面的多次会对话。AI导出鸭
javascript·人工智能·ai·小程序·电脑
去伪存真1 小时前
从乱码到高精度检索:探矿业务中 TXT、Word、PDF 与网页的 RAG 清洗之道
前端·agent
两个西柚呀1 小时前
JS事件总结
前端·javascript·css
小狼154541 小时前
拼多多订单数据导出 CSV 实战:接口分页、字段平铺与 5 个数据坑,多多开票助手
java·前端·javascript
搬砖的小码农_Sky1 小时前
AI Agent:Node.js和浏览器运行环境的本质区别
javascript·node.js·人机交互