在一些场景下,我们可能会频繁地发起一些相同的请求,这时就需要考虑如何取消重复请求。比如,当用户频繁触发某个接口的请求时,可能会导致重复请求的问题,这不仅浪费资源,还可能导致数据不一致性或其他意想不到的问题。在本文中,我们将探讨如何使用 Axios 取消重复请求,并介绍几种实现方法。
取消重复请求的概念
取消重复请求是指在发送新的网络请求之前,检查之前是否已经有相同请求在进行中,如果有,则取消之前的请求,只发送最新的请求。这样可以避免服务器端处理过多的重复请求,提高请求效率,并减轻服务器负担。
Axios 取消重复请求的方法
1.通过请求拦截器与响应拦截器实现
这是最常见的一种方法,通过 Axios 的请求拦截器和响应拦截器来实现取消重复请求。我们可以使用一个变量来保存之前的请求,并在新请求发起时,检查是否存在相同的请求,若存在,则取消之前的请求。
示例代码如下(请确保你已经安装了 Axios):
// 在合适的位置导入 Axios
import axios from 'axios';
// 变量用于保存之前的请求
let pendingRequest = null;
// 创建 Axios 实例
const instance = axios.create();
// 请求拦截器
instance.interceptors.request.use(config => {
// 在发送新请求前取消之前的请求
if (pendingRequest) {
pendingRequest.cancel('Request canceled due to duplicate request.');
}
pendingRequest = config;
return config;
});
// 响应拦截器
instance.interceptors.response.use(response => {
// 请求完成后,将 pendingRequest 置为 null
pendingRequest = null;
return response;
}, error => {
// 请求出错时,将 pendingRequest 置为 null
pendingRequest = null;
return Promise.reject(error);
});
export default instance;
2.使用 Axios CancelToken
Axios 提供了 CancelToken 的 API,可以用来取消请求。我们可以在发送请求时创建一个 CancelToken,并将它传递给请求配置中。当我们想要取消请求时,调用 CancelToken 的 cancel 方法即可。
示例代码如下:
import axios from 'axios';
// 创建 CancelToken 实例
const source = axios.CancelToken.source();
// 发送网络请求
axios.get('https://api.example.com/data', {
cancelToken: source.token,
})
.then(response => {
// 处理响应
})
.catch(error => {
if (axios.isCancel(error)) {
console.log('Request canceled', error.message);
} else {
// 处理其他错误
}
});
// 取消请求
source.cancel('Request canceled due to duplicate request.');
3.为每个请求实例设置单独的 CancelToken
如果我们需要为每个请求实例单独设置 CancelToken,可以这样实现:
const getUser = (id) => {
const source = axios.CancelToken.source();
return axios.get(`/user/${id}`, {
cancelToken: source.token
}).catch(thrown => {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
}
});
}
const request1 = getUser(1);
// 取消请求
request1.cancel('Cancel this request');
4.使用 axios.all 批量取消请求
如果我们需要批量取消一组请求,可以使用 axios.all 方法,通过向 axios.all 传入多个请求实例,我们就可以一次性地取消这一组请求:
const request1 = axios.get('/api/1');
const request2 = axios.get('/api/2');
axios.all([request1, request2]).then(axios.spread((res1, res2) => {
// 批量处理结果
}));
// 取消所有请求
request1.cancel();
request2.cancel();
5.在组件卸载时取消请求
在组件即将卸载时,我们也可以取消未完成的请求。例如在 React 组件中,通过保存 CancelToken 源到 ref 中,我们可以在组件卸载前取消未完成的请求。
import React, { useEffect, useRef } from 'react';
import axios from 'axios';
function MyComponent() {
const cancelToken = useRef(axios.CancelToken.source());
useEffect(() => {
const fetchData = () => {
axios('/data', {
cancelToken: cancelToken.current.token
})
}
fetchData();
return () => {
cancelToken.current.cancel();
}
}, []);
// ...
}
实践案例
假设我们有一个搜索功能,用户在输入框中输入内容后,会发送搜索请求。如果用户在短时间内频繁输入内容,我们希望只发送最后一次输入的搜索请求,取消之前的搜索请求。
import axios from 'axios';
let cancelTokenSource = null;
function searchQuery(query) {
// 取消之前的搜索请求
if (cancelTokenSource) {
cancelTokenSource.cancel('重复的搜索查询,取消请求。');
}
// 创建新的 CancelToken 实例
cancelTokenSource = axios.CancelToken.source();
axios.get('https://api.example.com/search', {
params: { q: query },
cancelToken: cancelTokenSource.token,
})
.then(response => {
// 处理搜索结果
})
.catch(error => {
if (axios.isCancel(error)) {
console.log('查询取消', error.message);
} else {
// 处理其他错误
}
});
}
在这个案例中,我们使用了方法二中的 Axios CancelToken 来实现取消重复搜索请求。每次用户输入内容时,都会取消之前的搜索请求,并创建一个新的 CancelToken 实例用于新的请求。
使用 Apifox 来 Mock 数据
Apifox = Postman + Swagger + Mock + JMeter,Apifox 支持调试 http(s)、WebSocket、Socket、gRPC、Dubbo 等协议的接口,并且集成了 IDEA 插件。在后端人员写完服务接口时,测试阶段可以通过 Apifox 来校验接口的正确性,图形化界面极大的方便了项目的上线效率。
更为重要的是,Apifox 能够 Mock 数据,其集成了 Mock.js 库,允许你自定义规则,并且可以编写脚本,强大的 Mock 功能可以让前端开发人员不再苦苦等待后端提供接口,自己就能提前造各种各样的数据出来,可视化操作让你点点鼠标就能生成可观的人性化数据。
提示与注意事项
- 在方法一中,我们使用了 Axios 的拦截器来实现取消重复请求,需要注意拦截器的调用顺序,确保在合适的时机取消之前的请求。
- 使用 Axios CancelToken 来取消请求时,需要注意每次请求都要创建新的 CancelToken 实例,确保每个请求都有独立的 CancelToken 对象。
- 可以为每个请求实例单独设置 CancelToken,也可以通过 axios.all 批量取消请求。
- 使用同一个 CancelToken 可以取消一组请求。
- 在组件卸载时,可以取消未完成的请求。
- 为了更好地用户体验,可以考虑设置一个延时,在用户输入内容后等待一段时间再进行搜索请求,避免用户频繁输入导致的请求频繁触发。
总结
本文介绍了 Axios 如何取消重复请求的几种方法:通过请求拦截器与响应拦截器实现,以及使用 Axios CancelToken等。取消重复请求可以提高请求效率,减轻服务器负担,并提升用户体验。在实践中,根据具体场景选择合适的方法来取消重复请求,确保代码的可靠性和性能。
知识扩展:
参考链接:
- Axios 官方文档:https://axios-http.com/docs/intro