zoukankan      html  css  js  c++  java
  • Vue中断axios请求-切换页面+重复请求

    切换页面时中断

    一、概述

    在Vue单页面开发过程中,遇到这样的情况,当我切换页面时,由于上一页面请求执行时间长,切换到该页面时,还未执行完,这时那个请求仍会继续执行直到请求结束,此时将会影响页面性能,并且可能对现在页面的数据显示造成一定影响

    所以我们应该,切换页面前中断前面所有请求

    二、解决方法

    在main.js中,重新封装axios请求,在router.beforeEach强制中断请求

    Vue.prototype.$http= axios;
    //Vue函数添加一个原型属性$axios 指向axios,这样vue实例或组件中不用再去重复引用Axios 直接用this.$axios就能执行axios 方法
    const CancelToken = axios.CancelToken;
    Vue.$httpRequestList=[];
    
    Vue.prototype.$ajax = (type, url, data) => {
        return new Promise((resolve, reject) => {   //封装ajax
            var aa = {
                method: type,
                url: url,
                cancelToken: new CancelToken(c => {  //强行中断请求要用到的
                    Vue.$httpRequestList.push(c);
                })
            }
            var json = (type == 'get') ? Object.assign(aa, { params: data }) : Object.assign(aa, { data: data });
            var ajax = Vue.prototype.$http(json).then(res => {
                resolve(res);
            }).catch(error => {   //中断请求和请求出错的处理
                    if (error.message == "interrupt") {
                        console.log('已中断请求');
                        return;
                    } else {
                        reject(error);
                    }
                })
            return ajax;
        })
    };
    
    
    router.beforeEach((to, from, next) => {   //路由切换检测是否强行中断,
        if(Vue.$httpRequestList.length>0){        //强行中断时才向下执行
            Vue.$httpRequestList.forEach(item=>{
                item('interrupt');//给个标志,中断请求
            })  
        }
        next();    
    });
    

    使用请求

    this.$axios('get',url,param).then(res=>{
    
    }).catch(err=>{
    
    });
    

    三、分析解读

    axios中文官网(http://www.axios-js.com/zh-cn/docs/)对cancel token 的说明

    使用cancel token取消请求

    方法一、使用cancelToken.sourse工厂方法创建cancel token

    const CancelToken = axios.CancelToken;
    const source = CancelToken.source();
    
    axios.get('/user/12345', {
      cancelToken: source.token
    }).catch(function(thrown) {
      if (axios.isCancel(thrown)) {
        console.log('Request canceled', thrown.message);
      } else {
         // 处理错误
      }
    });
    axios.post('/user/12345', {
      name: 'new name'
    }, {
      cancelToken: source.token
    })
    // 取消请求(message 参数是可选的)
    source.cancel('Operation canceled by the user.');
    

    方法二、通过传递一个 executor 函数到 CancelToken 的构造函数来创建 cancel token:

    const CancelToken = axios.CancelToken;
    let cancel;
    
    axios.get('/user/12345', {
      cancelToken: new CancelToken(function executor(c) {
        // executor 函数接收一个 cancel 函数作为参数
        cancel = c;
      })
    });
    
    // cancel the request
    cancel();
    

    重复请求时中断

    instance.interceptors.request.use(config => {
        config.cancelToken = new CancelToken(c => { 
            if(hasKey(this.queue,url)) {
                c(url);
            }else{
                this.queue[url] = true;
            };
        })
        return config
    }, error => {
        //return Promise.reject(error)
    })
    
  • 相关阅读:
    3.for in循环
    2.break与continue
    1.XHTML框架结构
    lamda表达式在EF中的应用
    View数据呈现相关技术
    ASP.NET MVC 4 技术讲解
    ASP.NET MVC 相关的社群与讨论区
    C# 随机红包算法
    圆圈里带 小写字母,大写字母
    使用SQL语句 检测 MSSQL死锁
  • 原文地址:https://www.cnblogs.com/ajaemp/p/11905901.html
Copyright © 2011-2022 走看看