统一接口多次请求,造成数据混乱的问题

1,775 阅读2分钟

首先这里描述一下问题

      vue项目不同路由使用同一组件,当这些路由切换的时候改变请求参数,但是统一接口。这样可能因为响应时间的问题造成a页面切到b页面再切回a页面,此时显示的是b页面的数据。造成这样的原因是接口返回时间的问题。所以就想到用axiso的cancelToken方法去cancel在pengidng的请求。

  • 实现方式一:全局的修改

import axios from 'axios';
    let pending = []; //声明一个数组用于存储每个ajax请求的取消函数和ajax标识
    let cancelToken = axios.CancelToken;
    let cancelPending = (pe) => {        for(let p in pending){
            //当当前请求在数组中存在时执行函数体
            if(pending[p].u === pe.url + '&' + pe.method) {                 
                pending[p].f(); //执行取消操作
                pending.splice(p, 1); //把这条记录从数组中移除
            }
        }
    }
    
    //http request 拦截器
    axios.interceptors.request.use(
    config => {
      // -------------------------------------------------------------
      cancelPending(config); //在一个ajax发送前执行一下取消操作    
      config.cancelToken = new cancelToken((c)=>{
         // 这里的ajax标识我是用请求地址&请求方式拼接的字符串,当然你可以选择其他的一些方式
         pending.push({ u: config.url + '&' + config.method, f: c });  
      });
      // ------------------------------------------------------------------
      return config;
    },
    error => {
      return Promise.reject(err);
    }
  );
  //http response 拦截器
  axios.interceptors.response.use(
    response => {
      //-----------------------------------
        //在一个ajax响应后再执行一下取消操作,把已经完成的请求从pending中移除
      cancelPending(res.config);       
      //-------------------------
      return response;
    },
    error => {
    //这段不加报错
     if (axios.isCancel(error)) {      //判断是否取消了请求      return Promise.reject(error);    }      return Promise.reject(error)
    }
  )

  • 方法二:局部修改

/**request.js**/import { request } from "../request";import axios from "axios";


export function getEventList(params, _this) {  // 解决多次重复发送同一请求造成数据混乱  const CancelToken = axios.CancelToken;  return request({    method: "GET",    url: "***",    params: {      ...params    },    cancelToken: new CancelToken(function executor(c) {      _this.cancelAjax = c;    })  });}/****/
if (typeof this.cancelAjax === "function") {        this.cancelAjax();      }getEventList(this.searchParams, this)        .then(res => {          if (res.data) {            .....        })        .catch(err => {          console.log(err);        });

这样就可以解决问题了,不过这种问题好像比较不常见,用放重复点击或者loading,都可以避免这个问题。可是我们业务有这个需求,所以难受。

方法不一定很好用,如果大神有什么好的方法,或者有什么错误的地方,欢迎批评指正。谢谢!