vue中取消重复请求需用abortcontroller实现“识别重复+主动取消”,通过唯一key映射pending请求并统一在拦截器中管理,防抖仅适用于按钮点击等简单场景。

Vue 项目中取消重复请求,核心是“识别重复 + 主动取消”,而不是等请求发出去再拦。重点不在防点几次按钮,而在于同一接口在 pending 状态下被多次调用时,只保留最后一次,取消前面所有未响应的请求。
用 AbortController 替代已弃用的 CancelToken
axios 自 v0.22.0 起推荐使用 AbortController(原生 fetch 标准),CancelToken 已标记为废弃,新项目务必避免使用。
- 每个请求创建独立 controller:
const controller = new AbortController() - 将
controller.signal传入 axios 配置:signal: controller.signal - 需要取消时直接调用
controller.abort(),无需判断错误类型 - 注意:abort 后的请求会抛出
DOMException: abort错误,建议在 catch 中静默处理或过滤
请求唯一标识 + 取消映射表
光有 controller 不够,关键是要知道“哪个请求该被取消”。需为每个请求生成唯一 key,比如:method + url + JSON.stringify(params)(GET 用 params,POST 建议用 data 的字符串化)。
- 维护一个 Map 或对象:如
const pendingRequests = new Map() - 发起请求前,先检查 key 是否已存在;若存在,执行
pendingRequests.get(key)?.abort() - 然后新建 controller,存入 map:
pendingRequests.set(key, controller) - 请求完成(无论成功或失败)后,从 map 中删除该 key
在 axios 拦截器里统一处理
把上述逻辑收口到请求拦截器和响应拦截器,业务层完全无感。
- 请求拦截器:生成 key → 检查并取消旧请求 → 创建新 controller → 注入 signal → 存 map
- 响应拦截器:成功或失败后,根据 config 获取 key,从 map 删除
- 可加白名单机制,对登录、上传等不适用取消的接口跳过该逻辑
- 避免跨组件冲突:key 里可加入模块名或业务标识,如
user/list?tab=active
简单场景可用防抖,但慎用于数据类请求
按钮点击类操作(如搜索、提交)可用防抖(debounce),延迟几百毫秒再发请求。但要注意:
- 防抖只解决“用户手快”,不解决“代码多处调用同一接口”的问题(比如多个组件同时初始化)
- 对实时性要求高的列表加载、详情页,防抖会导致明显卡顿或旧数据残留
- 防抖 + 请求取消组合使用更稳妥:UI 层防抖 + 请求层兜底取消
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











