axios 封装取消重复请求
时间: 2025-03-27 19:37:21 浏览: 47
### 使用 Axios 封装取消重复请求
为了实现取消重复请求的功能,可以利用 `axios` 提供的 `CancelToken` 和拦截器机制。下面是一个完整的解决方案,展示了如何通过自定义方法来管理待处理的请求并确保不会发出重复请求。
#### 创建全局变量存储待处理请求
首先声明一个 Map 对象用于保存当前所有的挂起请求及其对应的取消函数:
```javascript
const pendingRequests = new Map();
```
#### 定义辅助工具类
接着编写几个帮助函数以便于后续逻辑调用:
- **getPendingRequestKey**: 构建唯一键名作为标识符;
- **addPendingRequest**: 向集合中添加新成员;
- **removePendingRequest**: 移除已完成或被终止的任务;
```javascript
// 获取唯一的请求key
function getPendingRequestKey(config) {
return [
config.method,
config.url,
JSON.stringify(config.params),
JSON.stringify(config.data)
].join('&');
}
// 添加到pending队列里
function addPendingRequest(config, cancelFn) {
const key = getPendingRequestKey(config);
if (!pendingRequests.has(key))
pendingRequests.set(key, cancelFn);
}
// 从pending队列删除
function removePendingRequest(config) {
const key = getPendingRequestKey(config);
if (pendingRequests.has(key)) {
const cancelFn = pendingRequests.get(key);
cancelFn('Duplicate request was cancelled.');
pendingRequests.delete(key);
}
}
```
#### 配置 axios 请求/响应拦截器
接下来设置两个拦截器分别负责在每次发起 HTTP 调用前检查是否有相同 URL 正处于等待状态以及接收服务器返回的数据后清理掉对应条目:
```javascript
import axios from 'axios';
// 设置默认超时时间和基础路径等参数...
axios.defaults.timeout = 5000;
axios.defaults.baseURL = '/api/';
// 请求拦截器
axios.interceptors.request.use(
config => {
// 判断是否允许取消
if (config.allowCancel !== false) {
// 检查是否存在相同的请求
removePendingRequest(config);
// 新增cancel token
config.cancelToken = new axios.CancelToken(cancel => {
addPendingRequest(config, cancel);
});
}
return config;
},
error => Promise.reject(error)
);
// 响应拦截器
axios.interceptors.response.use(
response => {
removePendingRequest(response.config);
return response;
},
error => {
if (axios.isCancel(error)) {
console.warn(`Request canceled: ${error.message}`);
} else {
// 清理失败的请求
removePendingRequest(error.config || {});
}
return Promise.reject(error);
}
);
```
#### 发送带有取消功能的 GET 请求实例
最后展示一段实际应用场景下的代码片段,这里假设有一个获取加密货币行情数据的需求场景:
```javascript
async function fetchCryptoData(params) {
try {
const result = await axios({
method: 'GET',
url: '/crypto/prices', // API endpoint
params,
allowCancel: true // 开启此选项以启用去重特性
});
console.log(result.data); // 输出结果
return result;
} catch (e) {
throw e;
}
}
```
上述代码实现了基于 `axios` 库的一套简单而有效的防止重复提交方案[^2]。每当有新的请求到来时,程序会先尝试查找是否存在完全一致的历史记录——即同一 URI 下携带相等查询字符串与 body 参数组合而成的关键字存在于 `pendingRequests` 中;一旦发现匹配项则立即执行关联的取消指令,并更新映射表使其保持最新状态。反之亦然,在正常情况下新增加一条记录直至收到服务端反馈为止才会将其清除出去。
阅读全文
相关推荐



















