防止接口重复请求

140 阅读1分钟

最近遇到一个问题,刚进入页面时候有个接口请求了两次。而且这个接口比较耗时,单次就要6s.. 一般接口重复请求想的是防抖,经过代码排查调用的函数在两个不同组件,不适合 另外一种方式就是使用axios CancelToken取消重复请求,具体代码如下:

  1. 根据URL、参数等生成唯一KEY
function generateKey(config){
  const {method, url, params, data } = config;
  return [method, url, qs.stringify(params), qs.stringify(data)].join('&')
}
  1. 创建一个请求队列、包括加入、移除队列
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);
  }
}
  1. 请求拦截、判断当前请求是否已发送过,如果已发送就取消之前发送的
service.interceptors.request.use(config=>{
    removereqQueue(config); // 检查是否重复发送请求
    addreqQueue(config); //将本次请求加入请求队列
    
    //此处省略很多行
    
    return config
})
  1. 拦截响应,请求成功之后移除队列
service.interceptors.response.use(
response=>{
   removereqQueue(response.config); //请求从请求队列移除
},
error=>{
    removereqQueue(error.config || {}); //请求从请求队列移除
}
)