Axios请求超时重发机制

Axios 超时重新请求实现方案

在 Axios 中实现超时重新请求可以通过以下几种方式:

1. 使用拦截器实现自动重试

javascript 复制代码
import axios from 'axios';

// 创建axios实例
const instance = axios.create();

// 设置超时时间
instance.defaults.timeout = 5000;

// 最大重试次数
const MAX_RETRY = 3;

// 添加请求拦截器
instance.interceptors.response.use(undefined, (error) => {
  const config = error.config;
  
  // 如果配置不存在或未设置重试选项,则拒绝
  if (!config || !config.retry) return Promise.reject(error);
  
  // 设置重试次数变量
  config.__retryCount = config.__retryCount || 0;
  
  // 检查是否已达到最大重试次数
  if (config.__retryCount >= config.retry) {
    return Promise.reject(error);
  }
  
  // 增加重试计数器
  config.__retryCount += 1;
  
  // 创建新的Promise来处理指数退避
  const backoff = new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, config.retryDelay || 1000);
  });
  
  // 返回Promise,在退避时间后重试请求
  return backoff.then(() => instance(config));
});

// 使用示例
instance.get('/api/data', {
  retry: MAX_RETRY, // 重试次数
  retryDelay: 1000 // 重试延迟时间(毫秒)
}).then(response => {
  console.log(response.data);
}).catch(error => {
  console.error('请求失败:', error);
});

2. 封装请求函数实现重试

javascript 复制代码
function requestWithRetry(url, options = {}, retryCount = 3) {
  return new Promise((resolve, reject) => {
    const attempt = (currentRetry) => {
      axios({
        url,
        ...options,
        timeout: options.timeout || 5000
      })
        .then(resolve)
        .catch((error) => {
          if (currentRetry <= 0 || !isRetryable(error)) {
            return reject(error);
          }
          
          console.log(`请求失败,剩余重试次数: ${currentRetry - 1}`);
          
          // 指数退避
          const delay = Math.pow(2, retryCount - currentRetry) * 1000;
          
          setTimeout(() => {
            attempt(currentRetry - 1);
          }, delay);
        });
    };
    
    attempt(retryCount);
  });
}

// 判断错误是否可重试
function isRetryable(error) {
  return (
    error.code === 'ECONNABORTED' || // 超时
    !error.response || // 无响应(网络错误)
    error.response.status >= 500 // 服务器错误
  );
}

// 使用示例
requestWithRetry('/api/data', { method: 'get' }, 3)
  .then(response => console.log(response.data))
  .catch(error => console.error('最终失败:', error));

3. 使用第三方库

也可以使用专门处理重试的库,如 axios-retry:

javascript 复制代码
import axios from 'axios';
import axiosRetry from 'axios-retry';

// 配置axios-retry
axiosRetry(axios, {
  retries: 3, // 重试次数
  retryDelay: (retryCount) => {
    return retryCount * 1000; // 重试延迟
  },
  retryCondition: (error) => {
    // 只在超时或5xx错误时重试
    return axiosRetry.isNetworkOrIdempotentRequestError(error) || 
      error.code === 'ECONNABORTED';
  }
});

// 正常使用axios
axios.get('/api/data', { timeout: 5000 })
  .then(response => console.log(response.data))
  .catch(error => console.error('请求失败:', error));

注意事项

  1. 幂等性:确保请求是幂等的(GET、HEAD、OPTIONS、PUT、DELETE等),POST请求重试可能导致重复操作
  2. 退避策略:建议使用指数退避策略,避免同时重试大量请求
  3. 用户体验:对于前端应用,应考虑用户等待时间,不宜设置过多重试次数
  4. 取消请求:如果用户导航离开页面,应取消未完成的请求

以上方案可以根据实际需求进行调整和组合使用。

相关推荐
014-code10 分钟前
Java 并发中的原子类
java·开发语言·并发
AI人工智能+电脑小能手13 分钟前
【大白话说Java面试题】【Java基础篇】第29题:静态代理和动态代理的区别是什么
java·开发语言·后端·面试·代理模式
善恶怪客13 分钟前
Java-数组和可变参数
java·开发语言
小编码上说14 分钟前
LSH(局部敏感哈希)分桶,海量数据下的相似性搜索解决方案
java·spring boot·缓存·langchain4j·lsh·局部敏感哈希·ai调用优化
计算机_毕业设计33 分钟前
java-springboot数字藏品系统 基于 SpringBoot 的区块链数字艺术品交易平台 Java 微服务架构下的加密藏品展示与拍卖系统计算机毕业设计
java·spring boot·课程设计
ONVO ncen34 分钟前
Redis6.2.6下载和安装
java
丑八怪大丑36 分钟前
JDK8-17新特性
java·开发语言
京师20万禁军教头1 小时前
37面向对象(高级)-main方法
java
书源丶1 小时前
三十五、Java 泛型——类型安全的「万能模板」
java·开发语言·安全
dovens1 小时前
SpringBoot集成MQTT客户端
java·spring boot·后端