1. 程式人生 > >【vue】切換路由頁面時,中止上個路由頁面未返回資料的請求

【vue】切換路由頁面時,中止上個路由頁面未返回資料的請求

背景:
通常情況下,介面返回會比較快,不會出現此類狀況。
但是也有可能是後臺介面也依賴於上游介面,那麼處理過程中可能會有一些延遲之類的問題。
當用戶的某些操作,比如快速切換選單,某些選單一進入頁面後,就會向後臺傳送請求,在請求未拿到資料時,就被使用者切換到下個路由頁面,那麼上個路由頁面的請求,在未處理的情況下,就還是處於在傳送中,為了處理請求的效率,所以做了些處理。

我的專案是通過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 => { rerurn 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();
	// ...此處其他程式碼省略
})
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();
});