最近遇到一個需求:就是在頁面請求很久的情況下頁面一直在loading狀態,此時用戶點擊物理返回鍵需要取消掉loading及當前還在請求的接口。
-
axios提供取消功能
由於整套http接口是基於axios來的,所以就去找了下官網的例子
axios取消 -
主要思路
設置一個全局對象來存儲當前頁面的頁面名稱,當前請求路徑,當前請求可取消函數,在路由變了那麼意味着頁面變了,來整體清除當前存儲的頁面http信息。 -
axios請求攔截設置
// cancelHttpRequest爲全局對象
// 調用cancelHttpRequest.set()來設置當前頁面請求信息
// isShowLoading 爲配置信息是否顯示loading
import cancelHttpRequest from '../utils/cancelHttpRequest'
const CancelToken = axios.CancelToken;
_axios.interceptors.request.use(config => {
isShowLoading &&
Toast.loading({
duration: 0,
mask: false,
forbidClick: true,
message: '加載中...',
});
config.cancelToken = new CancelToken((c) => {
cancelHttpRequest.set({
curPage: router.history.current.name,
requestUrl: config.url,
func: c,
});
});
})
- axios攔截響應頭設置
_axios.interceptors.response.use(resp=>{
// 你自己的相應邏輯
},error=>{
// 這裏重點在err的時候處理
// 清除toast
Toast.clear();
// 若手動取消http請求
if (!!error.message && error.message === 'handleByBack') {
return Promise.reject(error.message);
}else{
// 你其他業務錯誤或公共錯誤處理邏輯
}
})
- 路由afterEach執行清除
import cancelHttpRequest from '../utils/cancelHttpRequest'
router.afterEach((to, from) => {
cancelHttpRequest.cancelHttp()
})
- cancelHttpRequest.js
/**
* @module 針對http執行可取消操作封裝
* @author ljxin
* @tips cancelHttpRequest對象
* 私有變量 _dsHttp
* 暴露方法: set ,get ,cancelHttp
*/
const cancelHttpRequest = {
// 緩存當前頁面的所有http請求
_dsHttp: {},
/**
* @func 設置當前頁面的http請求
*/
set: (v) => {
const { curPage, requestUrl, func } = v;
// 判斷當前http集合中是否已有數據
if (Object.keys(cancelHttpRequest._dsHttp).length !== 0) {
// 是否是同一個頁面的請求
const cur_dsHttpPage = cancelHttpRequest._dsHttp['curPage'];
if (cur_dsHttpPage === curPage) {
let reqObj = {};
reqObj['requestUrl'] = requestUrl;
reqObj['func'] = func;
cancelHttpRequest._dsHttp['curReqInfo'].push(reqObj);
}
} else {
// 直接存入
cancelHttpRequest._dsHttp['curPage'] = curPage;
cancelHttpRequest._dsHttp['curReqInfo'] = [];
let reqObj = {};
reqObj['requestUrl'] = requestUrl;
reqObj['func'] = func;
cancelHttpRequest._dsHttp['curReqInfo'].push(reqObj);
}
// console.log('當前請求集合',cancelHttpRequest._dsHttp)
},
/**
* @func 獲取當前http請求集合
*/
get: () => {
return cancelHttpRequest._dsHttp;
},
/**
* @func 取消當前頁面的所有http請求
*/
cancelHttp: () => {
if (Object.keys(cancelHttpRequest._dsHttp).length !== 0) {
if (cancelHttpRequest._dsHttp['curReqInfo'].length !== 0) {
const cancelDs = cancelHttpRequest._dsHttp['curReqInfo'];
cancelDs.map((el) => {
// 這裏會響應:響應攔截的error
el.func('handleByBack');
});
// 重置集合
cancelHttpRequest._dsHttp = {};
}
}
},
};
export default cancelHttpRequest;