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

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)
      	}
	}
)

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

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

总结

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

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue路由切换,如果你想取消之前的所有请求操作,可以使用axios库的取消请求功能。 首先,在你的Vue项目中安装axios库: ```shell npm install axios ``` 然后,在你的请求代码中,创建一个axios的实例,并启用取消请求的功能: ```javascript import axios from 'axios'; // 创建axios实例 const instance = axios.create({ baseURL: 'https://api.example.com' // 替换为你的API地址 }); // 创建一个用于取消请求的取消令牌 const CancelToken = axios.CancelToken; let cancel; // 请求拦截器 instance.interceptors.request.use(config => { // 在每次请求前调用cancel函数取消之前的请求 if (cancel) { cancel(); } // 为每个请求添加取消令牌 config.cancelToken = new CancelToken(function executor(c) { cancel = c; }); return config; }, error => { return Promise.reject(error); }); export default instance; ``` 现在,你可以在Vue组件中使用这个axios实例来发送请求,并在切换路由取消之前的请求: ```javascript import axios from '@/utils/axios'; export default { methods: { fetchData() { axios.get('/data') .then(response => { // 处理响应数据 }) .catch(error => { // 处理错误 }); } }, beforeRouteLeave(to, from, next) { // 在离开当前路由取消请求 axios.cancel(); next(); } } ``` 在上面的例子中,我们在组件的`beforeRouteLeave`导航守卫中调用了`axios.cancel()`函数来取消之前的请求。这样,当你切换路由,之前的请求将被取消。 这是一种基本的方法来取消之前的请求,你可以根据具体的业务需求进行适当的调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值