基於axios針對物理返回鍵主動取消當前頁面http請求及loading

最近遇到一個需求:就是在頁面請求很久的情況下頁面一直在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;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章