在真實(shí)項(xiàng)目中燕酷,當(dāng)路由已經(jīng)跳轉(zhuǎn)籍凝,而上一頁(yè)的請(qǐng)求還在pending狀態(tài),如果數(shù)據(jù)量小還好苗缩,數(shù)據(jù)量大時(shí)饵蒂,跳到新頁(yè)面,舊的請(qǐng)求依舊沒(méi)有停止酱讶,這將會(huì)十分損耗性能退盯,這時(shí)我們應(yīng)該先取消掉之前還沒(méi)有獲得相應(yīng)的請(qǐng)求,再跳轉(zhuǎn)頁(yè)面泻肯。這里axios給我們提供了一個(gè)方法:
cancelToken
讓我們來(lái)看看cancelToken的使用方法:
官網(wǎng)方法一:
var CancelToken = axios.CancelToken;
var source = CancelToken.source();
axios.get('/user/12345', {
cancelToken: source.token
}).catch(function(thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// 處理錯(cuò)誤
}
});
// 取消請(qǐng)求(message 參數(shù)是可選的)
source.cancel('Operation canceled by the user.');
如果我要跳轉(zhuǎn)頁(yè)面的話渊迁,我調(diào)用source.cance()方法就可以干掉之前這個(gè)沒(méi)有請(qǐng)求完的請(qǐng)求了。
但是這個(gè)方法有個(gè)弊端软免,就是比較麻煩宫纬,每次都要手動(dòng)去調(diào)用source.cance()方法焚挠。怎么做到全局統(tǒng)一管理呢膏萧?
官網(wǎng)給了以下方法:
還可以通過(guò)傳遞一個(gè) executor 函數(shù)到 CancelToken 的構(gòu)造函數(shù)來(lái)創(chuàng)建 cancel token:
var CancelToken = axios.CancelToken;
var cancel;
axios.get('/user/12345', {
cancelToken: new CancelToken(function executor(c) {
// executor 函數(shù)接收一個(gè) cancel 函數(shù)作為參數(shù)
cancel = c;
})
});
// 取消請(qǐng)求
cancel();
根據(jù)這個(gè)方法:我們一步一步來(lái)實(shí)現(xiàn)它:
在main.js里寫(xiě)一個(gè)全局httpRequestList的空數(shù)組,用來(lái)裝我們的cancel函數(shù):
// main.js
Vue.$httpRequestList = []
再在我們封裝好的post,get請(qǐng)求里面蝌衔,將每一個(gè)請(qǐng)求里面都做一個(gè)將cancel函數(shù)推入的httpRequestList數(shù)組的動(dòng)作:
POST (url, data, errMsg) {
const CancelToken = axios.CancelToken
return axios.post(url, data, {
timeout: 30000,
cancelToken: new CancelToken(function executor (c) {
Vue.$httpRequestList.push(c)
})
}).then(checkStatus).then(res => checkCode(res, errMsg))
},
GET (url, params, errMsg) {
const CancelToken = axios.CancelToken
return axios.get(url, {
params: {
_t: +(new Date()),
...params
},
timeout: 30000,
cancelToken: new CancelToken(function executor (c) {
Vue.$httpRequestList.push(c)
})
}).then(checkStatus).then(res => checkCode(res, errMsg))
}
這樣我們的每一個(gè)請(qǐng)求里面榛泛,都包含了一個(gè)cancelToken對(duì)象。
在這之后我們要寫(xiě)一個(gè)執(zhí)行cancel方法的 方法:
import Vue from 'vue'
export const clearHttpRequestingList = () => {
if (Vue.$httpRequestList.length > 0) {
Vue.$httpRequestList.forEach((item) => {
item()
})
Vue.$httpRequestList = []
}
}
item就是之前每一個(gè)請(qǐng)求裝進(jìn)httpRequestList數(shù)組的cancel方法噩斟,item()執(zhí)行后曹锨,如果該請(qǐng)求是pending狀態(tài),那么可以直接取消掉剃允。執(zhí)行完后記得清空httpRequestList數(shù)組沛简。
最后我們回到main.js
在每次跳轉(zhuǎn)之前執(zhí)行clearHttpRequestingList()函數(shù)齐鲤。
router.beforeEach((to, from, next) => {
clearHttpRequestingList()
..........這下面是你的路由驗(yàn)證代碼..........
})
這樣就實(shí)現(xiàn)了每次路由跳轉(zhuǎn)之前,就清空之前出于pending狀態(tài)的請(qǐng)求椒楣,優(yōu)化了性能给郊。
如下圖所示: