axios 封装,支持取消重复请求

axios 封装,支持取消重复请求

import axios from 'axios';

// axios 实例
const axiosInstance = axios.create({
    
    
  // 配置 axios 实例
});

// 存放正在进行的请求
const pendingRequests = new Map();

// 取消重复请求
const cancelPendingRequest = (config) => {
    
    
  const requestKey = getRequestKey(config);
  if (pendingRequests.has(requestKey)) {
    
    
    const cancelToken = pendingRequests.get(requestKey);
    cancelToken.cancel('Duplicate request');
    pendingRequests.delete(requestKey);
  }
};

// 添加请求到 pendingRequests 中
const addPendingRequest = (config) => {
    
    
  const requestKey = getRequestKey(config);
  config.cancelToken = new axios.CancelToken((cancel) => {
    
    
    if (!pendingRequests.has(requestKey)) {
    
    
      pendingRequests.set(requestKey, cancel);
    }
  });
};

// 生成请求 key
const getRequestKey = (config) => {
    
    
  const {
    
     method, url, params, data } = config;
  return `${
      
      method}_${
      
      url}_${
      
      JSON.stringify(params)}_${
      
      JSON.stringify(data)}`;
};

// 请求拦截器
axiosInstance.interceptors.request.use(
  (config) => {
    
    
    cancelPendingRequest(config);
    addPendingRequest(config);
    return config;
  },
  (error) => {
    
    
    return Promise.reject(error);
  }
);

// 响应拦截器
axiosInstance.interceptors.response.use(
  (response) => {
    
    
    const requestKey = getRequestKey(response.config);
    pendingRequests.delete(requestKey);
    return response;
  },
  (error) => {
    
    
    if (axios.isCancel(error)) {
    
    
      console.log('Request cancelled:', error.message);
      return Promise.reject(error);
    }
    return Promise.reject(error);
  }
);

export default axiosInstance;

使用时,直接引入该文件,通过 import axios from ‘路径’ 引入该 axios 实例,就可以使用了。该封装会在请求拦截器中判断当前请求是否与正在进行的请求相同,如果相同则取消之前的请求,并在 pendingRequests 中存放当前请求的 cancel token。在响应拦截器中,会从 pendingRequests 中删除该请求的 cancel token。

如果需要取消正在进行的请求,可以在组件的生命周期中调用 axios.cancel(requestKey) 方法,该方法会根据请求的 key 取消对应的请求。可以使用一个变量来存储当前组件的请求 key,当组件销毁时,取消所有的请求:

import axios from './axios';

export default {
    
    
  data() {
    
    
    return {
    
    
      requestKey: null, // 当前组件的请求 key
    };
  },
  created() {
    
    
    this.requestData();
  },
  beforeDestroy() {
    
    
    axios.cancel(this.requestKey);
  },
  methods: {
    
    
    async requestData() {
    
    
      const {
    
     data } = await axios.get('/api/data', {
    
     cancelToken: this.$axios.CancelToken });
      // 处理请求数据
    },
  },
};

猜你喜欢

转载自blog.csdn.net/NIKKT/article/details/130513825