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. 取消请求:如果用户导航离开页面,应取消未完成的请求

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

相关推荐
萧瑟余晖6 小时前
Java深入解析篇三十六之分布式系统详解
java·开发语言·分布式
KaKa_大王7 小时前
关于秒杀项目的一些理解
java·学习
tomla7 小时前
使用Java VisualVM观察过期对象引用现象
java
M1A17 小时前
Spring Boot YAML 配置读取完全指南:从基础到微服务
java
古法安卓7 小时前
Android-SELinux 策略调试实战:从 AVC 日志到策略修复
android·java·android studio
todoitbo7 小时前
飞算JavaAI的多租户权限隔离实测
java·springboot·ai编程·java开发·飞算javaai·java代码生成
星空7 小时前
Springboot复习
java·spring boot·spring
Dicky-_-zhang7 小时前
大模型部署架构:从推理引擎到弹性扩缩容的工程实践
java·jvm
vHelios8 小时前
【电商项目】商品搜索开发复盘(1):根据需求拆解搜索接口的设计逻辑
java·微服务·es
茶本无香8 小时前
@PostConstruct 注解完全指南
java·postconstruct