背景:
通常情况下,接口返回会比较快,不会出现此类状况。
但是也有可能是后台接口也依赖于上游接口,那么处理过程中可能会有一些延迟之类的问题。
当用户的某些操作,比如快速切换菜单,某些菜单一进入页面后,就会向后台发送请求,在请求未拿到数据时,就被用户切换到下个路由页面,那么上个路由页面的请求,在未处理的情况下,就还是处于在发送中,为了处理请求的效率,所以做了些处理。

我的项目是通过axios封装请求,此处要用到axios中的cancelToken,我通过网上整理的,搜集了两种解决办法,一种是取消一个请求,另一种是取消上个路由中所有未返回的请求。

下面我贴下部分代码(取消所有未返回的请求):
xhttp.js,是项目中一个封装好的axios的js

import axios form 'axios'
// 定义全局变量clearRequest,在route.js中要用到
const clearRequest = {
	source: {
		token: null,
		cancel: null
	}
}
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
// 配置发送请求拦截器
axios.interceptors.request.use(config => {
	config.cancelToken = clearRequest.source.token;// 这句很重要
	return config
}, error => {
	return Promise.reject(error)
})
// ...此处省略其他代码
// 封装通用请求
export default {
	post (url,data) {
		return axios({
			method: 'post',
			url,
			data: data,
			timeout: 30000,
			cancelToken: source.token,// 这句很重要
			headers: {
				'X-Requested-With': 'XMLHttpRequest',
                'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
			}
			.then( (res) => {} )
			.catch( (res) => {} )
		})
	},
	get (url,data) {
			method: 'get',
			url,
			data: data,
			timeout: 30000,
			cancelToken: source.token,// 这句很重要
			headers: {
				'X-Requested-With': 'XMLHttpRequest'
			}
			.then( (res) => {} )
			.catch( (res) => {} )
	},
	clearRequest
}

每次路由变化前,执行cancel方法并且更新cancelToken。
route.js

import Vue from 'vue'
import Router from 'vue-router'
import { routers } from './route'
import axios from 'axios'
import http from '@/http/xhttp'
Vue.use(Router)

// 路由配置
const RouterConfig = {
	mode: 'history',
	routes: routers
}
export const router = new Router(RouterConfig)
router.beforeEach((to, from, next) => {
	// ...此处其他代码省略
	// 切换路由时清空上个路由未完成的所有请求
	const CancelToken = axios.CancenlToken;
	http.clearRequest.source.cancel && http.clearRequest.source.cancel();
	http.clearRequest.source = CancelToken.source();
	next();
	// ...此处其他代码省略
})

第二种,在网上搜寻后,做了个尝试,他只能实现取消一个请求
来自这里,贴下地址:(https://www.zhangshengrong.com/p/QrXejpmV1d/)
我复制出来一下

Vue.prototype.$ajax=axios;
const CancelToken = axios.CancelToken;
let cancel;
let cancelAjaxText = '中断成功';
Vue.prototype.post = function(url,data,loading){
 	var ajax = Vue.prototype.$ajax({
	   	method: 'post',
	   	url:url,
	   	data: data,
	   	cancelToken: new CancelToken(c => { //强行中断请求要用到的
	   	cancel = c
	   	})
	  }).then(res =>res.data,res=>{ //中断请求和请求出错都会走这里,我这里用 cancelAjaxText 来区别
	  	if(res.message == cancelAjaxText){
	  		return {status : false,msg:cancelAjaxText}
	  	}else{
	  		this.$confirm('登录过时,是否重新登录', '提示', {
			   	confirmButtonText: '确定',
			   	cancelButtonText: '取消',
			   	type: 'warning'
			  }).then(() => {
			   	window.location.href = Vue.prototype.url_head + '/';
			  }).catch(() => {

			  });
	  	}

			})
 	return ajax;
};

接入 axios ,在POST方法里加入 cancelToken 数据,在上面else中,中断请求和请求出错都会走那里,所以用一个msg来识别(因为接口返回中也有一个msg,统一一下);
以下是 中断请求的方法,放在 路由切换的监听 router.beforeEach 中 ,cancel 是中断的方法,在post 的 cancelToken 里面拿出来的

Vue.prototype.cancelAjax = function(){ //切换页面强行中断请求 router.beforeEach中用到
	if(cancel){
		cancel(cancelAjaxText);
	}
} 
router.beforeEach((to, from, next) => {
	<span style="white-space:pre;"> </span>Vue.prototype.cancelAjax()
	next();
}); 
Logo

前往低代码交流专区

更多推荐