解决多次切换页面导致接口请求过多而不响应数据

362 阅读2分钟

前言

开发环境一切正常,结果等项目上线后,发现在正式环境下多次切换页面导致接口不响应数据,最后显示链接被重置

解决方案

首先考虑是用户的网络问题导致的,但因为是政府项目,用的都是政务内网,所以应该不存在这个问题,之后可能就是请求接口的问题,问了后端,说是这个接口地址不是我们做的,没办法只能想着从前端解决,先来个简单粗暴的解决办法,直接限制用户切页面的速度(话说真的是,闲的没事切那么快干嘛)

一、限制切换页面速度

思路:类似于节流,设置一个节流阀,当用户切换页面时,将节流阀打开,设置一个定时器,三秒之后关上,关闭之后才能再次调用这个方法

<template>
  <div class="super-map-home">
    <!--子页面 -->
    <component :is="isCheckNav"></component>
    <!-- tabs切换 -->
    <div class="map-foot">
      <ul>
        <li
          :class="isCheckNav == 'superMap' ? 'chencknav' : ''"
          @click="changeNav('superMap')"
        >
          超级地图
        </li>
        <li
          :class="isCheckNav == 'floodPrevention' ? 'chencknav' : ''"
          @click="changeNav('floodPrevention')"
        >
          防汛专题
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
import superMap from "./superMap.vue"; //超级地图页面
import floodPrevention from "./floodPrevention.vue"; //超级地图页面
var switchingTimeLoading = false;
export default {
  components: {
    superMap,
    floodPrevention,
  },
  data() {
    return {
      isCheckNav: "superMap",
      isLoading: true,
    };
  },
  methods: {
    // 监听二级菜单导航
    // 限制用户切换时间
   changeNav(val) {
      if (!switchingTimeLoading) {
        switchingTimeLoading = true;
        this.isCheckNav = val;
        setTimeout(function() {
        switchingTimeLoading = false;
      }, 2500);
      } else {
        this.$message("此页面加载中 请稍后再试");
      }
    },
  },
  mounted() {},
};
</script>

这样的话当用户在切换三秒内切换页面的话就会出现提示

image.png

二、在用户切换到下一个页面时关闭上一个页面未请求完成的接口

在请求拦截器中的代码

// 封装axios请求
import axios from 'axios'
import Cookies from 'js-cookie'
import qs from 'qs'
import { clearLoginInfo,jumpTo } from '@/utils'
import isPlainObject from 'lodash/isPlainObject'const http = axios.create({
  baseURL: window.SITE_CONFIG.apiURL,
  timeout: 1000 * 180,
  withCredentials: true
})
​
window._axiosPromiseArr = []
/**
 * 请求拦截
 */
http.interceptors.request.use(config => {
  
    // 请求下一个页面时关闭上一个页面正在请求的接口 
  config.cancelToken = new axios.CancelToken(cancel =>{
    window._axiosPromiseArr.push({ cancel })
  })
  return config
}, error => {
  return Promise.reject(error)
})
​
/**
 * 响应拦截
 */
http.interceptors.response.use(response => {
  if (response.data.code === 401 || response.data.code === 10001) {
    clearLoginInfo()
    jumpTo("/Login")
    return Promise.reject(response.data.msg)
  }
  return response
}, error => {
  console.error(error)
  return Promise.reject(error)
})
​
export default http

在跳转发生的地方的代码

methods: {
    // 跳转的方法
    // 监听二级菜单导航
    changeNav(val) {
      this.isCheckNav = val
      window._axiosPromiseArr.forEach((ele,index) => {
        ele.cancel() // 路由跳转之前,清空(终止)上一个页面正在请求的内容
        delete window._axiosPromiseArr[index]// 清空请求的参数 清空请求的参数
      })
    }
}

如果是路由跳转的话,就写在路由守卫里

router.beforeEach((to, from, next) => {
  window._axiosPromiseArr.forEach((ele,index) => {
    ele.cancel() // 路由跳转之前,清空(终止)上一个页面正在请求的内容
    delete window._axiosPromiseArr[index] // 清空请求的参数
  })
  next();
})

之后切换页面的时候就会将上一个页面未加载完的接口自动取消了

image.png