基于axios针对物理返回键主动取消当前页面http请求及loading

本文介绍如何在使用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;

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值