axios防止多次点击请求生成多条数据

思路

定一个数组,请求时把url+method放入,以此判断唯一性,下一次请求验证是否是同个请求,是的话,执行axioscancel方法,请求完了从数组里面清除该请求。

code

//#region 
/**
 * 防止网络过慢时 发送重复请求
 * 在下一个请求未完成时 取消掉之后的重复请求
 */

let pending = []
let CancelToken = axios.CancelToken
let removePending = (config, f) => {
  let flagUrl = config.url + '&' + config.method
  console.log(pending)
  console.log(flagUrl)
  if (pending.indexOf(flagUrl) !== -1) {
    if (f) {     
     // console.log('--------romove request---------')
      f() // 执行取消操作
    } else {
     // console.log('--------splice pending array---------')
      pending.splice(pending.indexOf(flagUrl), 1)// 把这条记录从数组中移除
    }
  } else {
    if (f) {
    //  console.log('--------push pending array---------')
      pending.push(flagUrl)
    }
  }
}
//#endregion

const service = axios.create({
  //	  baseURL: process.env.BASE_API, // api的base_url
  //   timeout: 5000 // request timeout
});
service.interceptors.request.use(
  config => {
    if ((config.method === 'post' && config.url && config.url.indexOf('survey/isUsed/')<0)
      || config.method === 'put') {
      //  console.log('--------request in---------')
        config.cancelToken = new CancelToken((c) => {
        removePending(config, c)
      })
    }
    // Do something before request is sent
   
    return config;
  },
  error => {
    // Do something with request error
    console.log(error); // for debug
    // Promise.reject(error);
  }
);
/** 拦截器中统一处理错误提示*/
service.interceptors.response.use(
  response => {
    if (response.config.method === 'post' || response.config.method === 'put') {
    //  console.log('--------response in------------')
    // 这边 让splice pending 数组慢一点 防止请求过快 出现两条重复数据
      setTimeout(() => {
        removePending(response.config)
      },500);     
    }  //在一个ajax响应后再执行一下取消操作,把已经完成的请求从pending中移除
    // Do something with response data
   
    return response;
  },
  error => {    
  
    // Do something with request error
 
    return { data: {message:error.toString()} }; 

  }
);

遇到的问题

模拟慢网速是可以实现的,但是请求响应过快同样会放行。

解决方法

在请求响应之后,给清除该url的方法加500ms延迟,这样就可以解决,清除过快导致的判断失效问题。