📡 Axios 请求封装:解决重复请求与取消未响应请求
本项目封装了基于 axios
的 HTTP 请求类 Request
,用于自动管理重复请求、取消未响应请求等场景,提升接口调用的效率与用户体验。
🔧 核心功能概述
- 防止重复请求:
- 在发起新请求前判断是否存在相同请求,如果有,则主动取消上一次请求。
- 取消所有未响应请求:
- 提供静态方法
cancelAllPendingRequests
,可一次性中止所有尚未完成的请求。
- 提供静态方法
🧩 功能实现细节
✅ 请求唯一标识生成
每个请求根据其方法、URL、params
和 data
生成唯一键值,用于识别是否为重复请求。
ts
private static generateRequestKey(config: AxiosRequestConfig): string {
const { method, url, params, data } = config;
return [method, url, JSON.stringify(params), JSON.stringify(data)].join('&');
}
🔁 重复请求处理机制
在请求拦截器中:
- 通过
generateRequestKey
获取当前请求的唯一标识。 - 检查是否已有相同请求正在进行。
- 若存在,使用
AbortController
中止旧请求,并更新记录。 - 为当前请求创建新的
AbortController
,并存入pendingRequests
Map 中。
ts
if (pendingRequests.has(requestKey)) {
pendingRequests.get(requestKey)?.abort();
pendingRequests.delete(requestKey);
}
const controller = new AbortController();
res.signal = controller.signal;
pendingRequests.set(requestKey, controller);
🛑 响应处理与清理逻辑
在响应拦截器中,无论请求成功还是失败,都会移除对应的请求记录:
ts
const requestKey = Request.generateRequestKey(response.config);
pendingRequests.delete(requestKey);
如果是取消请求(如用户主动切换页面、重复请求等),则记录不会保留,也不会弹出错误提示。
🧹 批量取消所有未响应请求
提供一个静态方法 cancelAllPendingRequests
,当需要清空所有请求时(如路由切换、退出登录),调用此方法即可:
ts
public static cancelAllPendingRequests(): Promise<void> {
return new Promise((resolve) => {
pendingRequests.forEach((controller) => {
controller.abort();
});
pendingRequests.clear();
resolve();
});
}
📦 使用场景
- 页面快速切换时取消旧请求,防止数据错乱或内存泄漏。
- 用户多次点击相同操作按钮时,确保只处理最新请求。
- 后台任务或轮询中止机制。
- 全局错误处理与提示统一封装。
🚀 未来优化方向
- 增加白名单机制,允许某些接口重复发送请求。
- 配置化支持某些请求不参与去重逻辑。
- 针对大文件上传、下载的特殊处理策略。
📁 示例调用方式
ts
import Request from '@/utils/request';
const request = new Request({
baseURL: '/api',
timeout: 10000,
});
request.instance.get('/user/info').then((data) => {
console.log('User Info:', data);
});
// 取消所有请求(例如在页面卸载时调用)
Request.cancelAllPendingRequests();
✅ 小结
封装 axios
请求类不仅解决了重复请求的浪费问题,也提升了用户交互体验。结合 AbortController
实现取消机制,是现代前端接口管理中的推荐做法。
如需深入定制或拓展其他功能,可继续增强 Request
类的灵活性与配置性。