美文网首页工具前端开发社区vuejs
使用axios如何取消重复请求

使用axios如何取消重复请求

作者: 38abbaada646 | 来源:发表于2017-06-29 08:49 被阅读2179次

    axios官网文档上取消请求的两种方式

    使用CancelToken.source工厂创建一个取消令牌:

    var CancelToken = axios.CancelToken;
    var source = CancelToken.source();
    axios.get('/user/12345', {
      cancelToken: source.token
    }).catch(function(thrown) {
      if (axios.isCancel(thrown)) {
        console.log('Request canceled', thrown.message);
      } else {
        // 处理错误
      }
    });
    //取消请求(消息参数是可选的)
    source.cancel('操作被用户取消。');
    

    还可以通过将执行器函数传递给CancelToken构造函数来创建取消令牌:

    var CancelToken = axios.CancelToken;
    var cancel;
     
    axios.get('/ user / 12345',{
       cancelToken:new CancelToken(function executor(c){
         //一个执行器函数接收一个取消函数作为参数
         cancel = c;
       })
    });
     
    // 取消请求
    clear();
    

    根据文档上的第二种方法,我们可以在拦截器里统一处理取消重复请求

    let pending = []; //声明一个数组用于存储每个ajax请求的取消函数和ajax标识
    let cancelToken = axios.CancelToken;
    let removePending = (config) => {
        for(let p in pending){
            if(pending[p].u === config.url + '&' + config.method) { //当当前请求在数组中存在时执行函数体
                pending[p].f(); //执行取消操作
                pending.splice(p, 1); //把这条记录从数组中移除
            }
        }
    }
    
    //添加请求拦截器
    axios.interceptors.request.use(config=>{
         removePending(config); //在一个ajax发送前执行一下取消操作
         config.cancelToken = new cancelToken((c)=>{
            // 这里的ajax标识我是用请求地址&请求方式拼接的字符串,当然你可以选择其他的一些方式
            pending.push({ u: config.url + '&' + config.method, f: c });  
        });
         return config;
       },error => {
         return Promise.reject(error);
       });
    
    //添加响应拦截器
    axios.interceptors.response.use(response=>{
          removePending(res.config);  //在一个ajax响应后再执行一下取消操作,把已经完成的请求从pending中移除
          return response;
       },error =>{
          return { data: { } }; 返回一个空对象,主要是防止控制台报错
       });
    

    效果

    同一个请求,没有完成的请求将被取消


    未完成的ajax被取消

    结论

    利用这个方法,一方面可以防止重复点击不同页码导致的表格数据闪烁,另外可以做实时搜索,始终获取最新结果。

    相关文章

      网友评论

      • HT88888:Uncaught (in promise) Cancel {message: undefined} 楼主,加了这个就报这个错了,你知道是为什么吗?
      • 打1折的暧昧:最后取消重复请求会有些问题。第二次请求时后台已经接收到了请求。还是会生成2次相同的数据。
        落叶追风:因为u = config.url + '&' + config.method;因此在同一个请求,参数不同的时候也会导致取消,所以有的情况下取消上一个请求并不适用
        打1折的暧昧:@zs_a2be 赞,我也是这么处理的
        zs_a2be:我也发现了这个问题,不应改在判断重复的情况下取消上一个请求,而应该取消本次请求。我做了一下修改好像可以了
        let pending = []
        let CancelToken = axios.CancelToken
        let removePending = (config, f) => {
        let flagUrl = config.url + '&' + config.method
        if (pending.indexOf(flagUrl) !== -1) {
        if (f) {
        f() // 执行取消操作
        } else {
        pending.splice(pending.indexOf(flagUrl), 1)// 把这条记录从数组中移除
        }
        } else {
        if (f) {
        pending.push(flagUrl)
        }
        }
        }
        // http request 拦截器
        HTTP.interceptors.request.use(
        config => {
        if (config.method === 'post') {
        console.log('我是拦截')
        config.cancelToken = new CancelToken((c) => {
        removePending(config, c)
        })
        }
        return config
        },
        err => {
        return Promise.reject(err)
        })

        // http response 拦截器
        HTTP.interceptors.response.use(
        response => {
        if (response.config.method === 'post') {
        removePending(response.config)
        }
        return response
        },
        error => {
        pending = []
        return { data: {error: error} } // 返回接口返回的错误信息
        })

      本文标题:使用axios如何取消重复请求

      本文链接:https://www.haomeiwen.com/subject/rhuucxtx.html