• BUG:vue路由切换时终止异步请求


    项目场景:

    bug描述:在一个vue页面中,有异步数据请求的方法正在执行,此时切换到其他vue页面后,该异步请求不会停止。
    之前写项目时,没有注意到vue路由切换后,还没执行完毕的异步请求并没有随着页面的切换而结束。
    用户在当前访问页面中,异步请求的数据还没抓取完跳转到其他页面时,这个异步请求并不会终止,这对web性能和用户体验有着不小的影响。


    解决思路

    方法:利用axios的cancelToken取消还没执行完毕的异步请求,由路由守卫做处理,使用vuex将要取消的请求放入全局进行状态管理。

    简单介绍cancelToken:

    针对单个请求A发多次的情形(A1,A2…An), An都会带上cancelToken(标记),A(n+1)发起时会将An请求直接canceled(不再处理An请求响应)。

    1. 发起一次请求A1,且该请求中携带标识此次请求的id
    2. 发起一次请求A2(An表示针对同一个接口A的第n次请求),A2请求时取消原请求A1,请求A1被标识为canceled(network process工作结束)
    3. axios标记A1为请求异常,进入响应处理阶段(响应获取一个错误对象),请求A1结束。
    • cancelToken就是一个promise,这个promise的状态的改变由使用者自己决定(执行cancel函数)。同时,这个promise的then回调就会执行,取消request

    代码部分

    1. 在store中管理取消的请求操作

    // store.js
    const store = new Vuex.Store({
    	...
    	// store中对请求进行状态管理
      // 管理取消的请求操作
      state: {
        axiosArr: [] // 储存cancel token
      },
      mutations: {
        setAxiosArr (state, cancelAjax) {
          state.axiosArr.push(cancelAjax.cancelToken)
        },
        clearAxiosArr (state) {
          let message = '路由切换中断异步请求'
          state.axiosArr.forEach(item => {
            item()
          })
          state.axiosArr = []
        },
      },
    })
    
    export default store
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    2. axios封装

    对request做一个条件判:在发送请求设置cancel token(就是做个标记);
    再对response做一个条件判断:表达当请求失败时出现何种提示,不然会在控制台给出报错(虽然没什么影响)。

    axios.interceptors.request.use(
    	// 对axios进行封装,设置 request 处理操作
    	config => { 
    	  config.cancelToken = new axios.CancelToken(cancel => { // 在发送请求设置cancel token
    	    store.commit('setAxiosArr', { cancelToken: cancel })
    	  })
    	  return config
    	}, error => {
    	  // Do something with request error
    	  return Promise.reject(error)
    	}
    )
    axios.interceptors.response.use(
    	response => {
    		if (service.isCancel(error)) {
          		// 对axios进行封装,设置 request 和 response 的处理操作
          		return new Promise(() => {})
          	} else {
          		return Promise.reject(error)
          	}
    	}
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    3. 设置路由守卫对路由进行监听

    // 增加路由守卫对路由进行监听,在路由切换时对上一个路由的请求进行中断
    router.beforeEach((to, from, next) => {
    	store.commit('clearAxiosArr')   // 取消请求
    	// console.log('路由切换')
    	next()
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    总结

    最终实现效果:
    在这里插入图片描述
    可以看到切换vue页面后,正在执行的异步请求被中断了,从而保证了页面加载的性能和用户体验。

  • 相关阅读:
    Vue前后端项目开发指南(三)【后端Springboot项目的搭建】
    【油猴脚本 Greasemonkey】GM_xmlhttpRequest内部实现原理
    使用 Elasticsearch、OpenAI 和 LangChain 进行语义搜索
    Excel VBA教程之如何在功能区中显示 Excel 开发人员选项卡,启用vba(教程含源码)
    MybatisPlus中queryWrapper的or的使用
    怎么让机器认识你的手势?机器学习方向
    零数科技创新金融案例入选《2022全球区块链创新应用示范案例集》
    经典算法系列之(三):七大查找——二分查找
    【黑马-SpringCloud技术栈】【06】Feign(OpenFeign)
    TCL基础学习 -输出 赋值 替换和数学表达
  • 原文地址:https://blog.csdn.net/qq_43093129/article/details/126398689