前端实现超时请求重传

在网络不稳定的场景下,超时请求重传 是提升应用健壮性的关键策略。以下是前端实现请求超时重试的完整方案,涵盖 AxiosFetch API 两种主流方式,帮你轻松应对网络波动!


核心实现方案

1. 基于 Axios 实现(推荐)

Axios 提供了拦截器(interceptors)和配置项,非常适合实现超时重传。

完整代码示例

typescript 复制代码
import axios, { AxiosRequestConfig, AxiosError } from 'axios';

// 重试配置
const RETRY_COUNT = 3; // 最大重试次数
const RETRY_DELAY = 1000; // 重试延迟(ms)
const TIMEOUT = 5000; // 单次请求超时时间(ms)

// 创建 Axios 实例
const http = axios.create({ timeout: TIMEOUT });

// 请求拦截器:记录重试次数
http.interceptors.request.use((config: any) => {
  config.__retryCount = config.__retryCount || 0;
  return config;
});

// 响应拦截器:错误处理与重试
http.interceptors.response.use(null, async (error: AxiosError) => {
  const config = error.config;

  // 如果不是超时错误或达到重试上限,直接拒绝
  if (
    error.code !== 'ECONNABORTED' || 
    config.__retryCount >= RETRY_COUNT
  ) {
    return Promise.reject(error);
  }

  // 增加重试计数
  config.__retryCount += 1;

  // 延迟重试
  await new Promise(resolve => 
    setTimeout(resolve, RETRY_DELAY)
  );

  return http(config);
});

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

关键点说明

  1. 错误类型判断 :只重试超时错误(ECONNABORTED
  2. 重试控制 :通过 __retryCount 记录已重试次数
  3. 延迟重试:避免立即重试导致服务器压力骤增

2. 基于 Fetch API 实现

Fetch API 需要手动封装重试逻辑,适合原生场景。

完整代码示例

typescript 复制代码
const fetchWithRetry = async (
  url: string,
  options: RequestInit = {},
  retries: number = 3,
  delay: number = 1000
): Promise<Response> => {
  try {
    // 添加超时控制
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), 5000);
    
    const response = await fetch(url, {
      ...options,
      signal: controller.signal
    });
    
    clearTimeout(timeoutId);
    
    if (!response.ok) throw new Error(`HTTP ${response.status}`);
    return response;
  } catch (error) {
    if (retries <= 0) throw error;
    await new Promise(resolve => setTimeout(resolve, delay));
    return fetchWithRetry(url, options, retries - 1, delay);
  }
};

// 使用示例
fetchWithRetry('/api/data')
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(err => console.error('最终失败:', err));

关键点说明

  1. 超时控制 :通过 AbortController 实现
  2. 递归重试:通过递归调用实现次数控制
  3. 错误边界:区分网络错误和业务错误(HTTP状态码)

高级优化策略

1. 指数退避算法

重试间隔随时间指数增长,避免雪崩效应:

arduino 复制代码
const delay = Math.pow(2, retries) * 1000; // 2^n秒

2. 关键请求标记

对支付等关键请求启用重试,对普通查询请求禁用:

arduino 复制代码
if (config.isCritical) {
  // 执行重试逻辑
}

3. 用户提示优化

  • 首次失败显示"正在重试..."
  • 最终失败显示"网络不稳定,请手动重试"

各方案对比

方案 优点 缺点 适用场景
Axios 拦截器机制完善 需要封装 已有Axios的项目
Fetch 浏览器原生支持 手动实现复杂 追求轻量的项目
React Query 内置重试机制 需要引入额外库 React生态

总结

  1. Axios 方案:通过拦截器优雅实现,适合大多数项目
  2. Fetch 方案:更底层控制,适合特殊需求场景
  3. 优化策略:指数退避 + 智能提示提升用户体验
相关推荐
子洋38 分钟前
AI Agent 介绍
前端·人工智能·后端
徐同保42 分钟前
使用n8n自动发邮件
前端
dly_blog1 小时前
setup 函数完整指南!
前端·javascript·vue.js
霍理迪2 小时前
基础CSS语法
前端·css
粟悟饭&龟波功2 小时前
【GitHub热门项目精选】(2025-12-19)
前端·人工智能·后端·github
流浪法师122 小时前
MyPhishing-Web:AI 驱动的钓鱼邮件检测可视化平台
前端·人工智能
写代码的jiang2 小时前
【无标题】实战:Vue3 + Element Plus 实现树形选择器全量预加载与层级控制
前端·javascript·vue.js
晚烛2 小时前
实战前瞻:构建高可靠、低延迟的 Flutter + OpenHarmony 智慧交通出行平台
前端·javascript·flutter
WHOVENLY2 小时前
【javaScript】- 作用域[[scope]]
前端·javascript
来杯三花豆奶2 小时前
Vue3 Pinia 从入门到精通
前端·javascript·vue.js