最近遇到一个问题,刚进入页面时候有个接口请求了两次。而且这个接口比较耗时,单次就要6s.. 一般接口重复请求想的是防抖,经过代码排查调用的函数在两个不同组件,不适合 另外一种方式就是使用axios CancelToken取消重复请求,具体代码如下:
- 根据URL、参数等生成唯一KEY
function generateKey(config){
const {method, url, params, data } = config;
return [method, url, qs.stringify(params), qs.stringify(data)].join('&')
}
- 创建一个请求队列、包括加入、移除队列
const reqQueue = new Map();
function addreqQueue(config){
//调用生成唯一标识值函数, 生成Key
const requestKey = generateKey(config);
//为每个请求创建一个专属的 CancelToken(用于取消请求)
config.cancelToken = config.cancelToken || new axios.CancelToken((cancel)=>{
// 判断 reqQueue 中是否含有 requestKey,
// 将 requestKey 与 CancelToken 以键值对的形式保存到map对象中
if(!reqQueue.has(requestKey)){
reqQueue.set(requestKey,cancel)
}
});
}
function removereqQueue(config){
// 获取Key
const requestKey = generateKey(config);
if(reqQueue.has(requestKey)){
// 取消之前发出请求
const cancelToken = reqQueue.get(requestKey);
cancelToken(requestKey);
// 从队列移除
reqQueue.delete(requestKey);
}
}
- 请求拦截、判断当前请求是否已发送过,如果已发送就取消之前发送的
service.interceptors.request.use(config=>{
removereqQueue(config); // 检查是否重复发送请求
addreqQueue(config); //将本次请求加入请求队列
//此处省略很多行
return config
})
- 拦截响应,请求成功之后移除队列
service.interceptors.response.use(
response=>{
removereqQueue(response.config); //请求从请求队列移除
},
error=>{
removereqQueue(error.config || {}); //请求从请求队列移除
}
)