封装一个axios库并支持取消重复请求

封装一个支持取消重复请求的 axios 库是一个常见的需求,尤其是在前端开发中。以下是一个简单的示例,展示了如何实现这一功能:

  1. 安装 axios

如果你还没有安装 axios,可以使用 npm 或 yarn 进行安装:

npm install axios

yarn add axios
  1. 封装 axios

创建一个新的文件,例如 request.js,并添加以下代码:

import axios from 'axios';

// 用于存储请求的Map对象,key为请求的url+params+method的组合,value为请求的CancelToken源
const pendingRequests = new Map();

// 添加请求
const addPendingRequest = (config) => {
  const url = [
    config.method,
    config.url,
    qs.stringify(config.params), // 你可能需要安装qs库来处理params: npm install qs
    qs.stringify(config.data)
  ].join('&');
  config.cancelToken =
    config.cancelToken ||
    new axios.CancelToken((cancel) => {
      if (!pendingRequests.has(url)) {
        // 如果pendingRequests中没有这个url,就添加进去
        pendingRequests.set(url, cancel);
      } else {
        // 如果pendingRequests中有这个url,就取消之前的请求,并重新设置cancelToken
        const previousCancel = pendingRequests.get(url);
        previousCancel('Request canceled'); // 取消之前的请求
        pendingRequests.set(url, cancel); // 重置cancelToken
      }
    });
};

// 移除请求
const removePendingRequest = (config) => {
  const url = [
    config.method,
    config.url,
    qs.stringify(config.params),
    qs.stringify(config.data)
  ].join('&');
  if (pendingRequests.has(url)) {
    // 如果在pendingRequests中存在这个请求,就移除它
    const cancel = pendingRequests.get(url);
    cancel('Request finished'); // 请求完成后取消该请求,避免后续操作再次取消该请求(虽然理论上不应该发生)
    pendingRequests.delete(url);
  }
};

// 创建axios实例并添加拦截器来处理请求和响应
const service = axios.create({
  // 你可以在这里设置默认的axios配置,例如baseURL等
});

// 请求拦截器
service.interceptors.request.use(
  (config) => {
    addPendingRequest(config); // 在发送请求之前添加请求到pendingRequests中
    return config;
  },
  (error) => {
    // 处理请求错误
    return Promise.reject(error);
  }
);

// 响应拦截器
service.interceptors.response.use(
  (response) => {
    removePendingRequest(response.config); // 在请求完成后从pendingRequests中移除请求
    return response;
  },
  (error) => {
    // 如果是取消请求的错误,则不进行错误处理
    if (axios.isCancel(error)) {
      console.log('Request canceled', error.message);
      return Promise.resolve('Request canceled'); // 你可以根据需要修改这里的处理方式,例如返回一个特定的错误对象等。
    } else {
      // 处理其他响应错误
      return Promise.reject(error);
    }
  }
);

export default service; // 导出封装后的axios实例以供其他文件使用。

注意:这个示例使用了 qs 库来序列化 params 和 data,以便它们可以作为 URL 的一部分。你可能需要使用 npm install qs 来安装这个库。如果你不想使用 qs,你可以根据自己的需求修改这部分代码。
3. 使用封装的 axios

在你的其他文件中,你可以这样使用封装后的 axios

import request from './request'; // 引入封装后的axios实例

// 发送GET请求示例
request.get('/api/data', { params: { id: 1 } })
  .then((response) => {
    console.log(response.data); // 处理响应数据
  })
  .catch((error) => {
    console.error('Error:', error); // 处理错误
  });
posted @ 2025-01-05 09:27  王铁柱6  阅读(91)  评论(0)    收藏  举报