You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何基于try/catch与Promise实现接口500错误重试?

接口返回500错误时的高效重试方案

针对接口500错误(服务器端临时故障),最可行的方案是实现带指数退避的重试逻辑,既保证请求有机会成功,又不会因频繁重试给服务器造成额外压力。同时结合AbortController处理组件卸载或依赖变化时的请求取消,避免竞态问题。

步骤1:封装通用重试函数

先写一个可复用的重试工具函数,核心逻辑是捕获请求错误,判断是否为500状态码,若满足则按指数退避延迟后重试,直到达到最大重试次数:

const retryWithExponentialBackoff = async (
  requestFn,
  maxRetries = 3,
  initialDelay = 1000 // 初始延迟1秒
) => {
  let attempt = 0;
  while (attempt < maxRetries) {
    try {
      // 每次重试创建新的AbortController,避免取消后续请求
      const controller = new AbortController();
      const result = await requestFn(controller.signal);
      return result;
    } catch (error) {
      attempt++;
      // 根据API错误结构判断是否为500错误
      if (error.response?.status !== 500 || attempt >= maxRetries) {
        throw error; // 非500错误或达到重试上限,抛出错误
      }
      // 指数退避:延迟时间随重试次数翻倍
      const delay = initialDelay * Math.pow(2, attempt - 1);
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
};

步骤2:改造原有useEffect逻辑

将原API调用替换为调用重试函数,同时处理依赖变化时的请求取消:

useEffect(() => {
  const controller = new AbortController();
  const fetchData = async () => {
    setIsLoadingGraph(true);
    try {
      setCSV(createPayload());
      const response = await retryWithExponentialBackoff(async (signal) => {
        // 传递AbortSignal给API请求,支持取消操作
        return api.generateDataByFilters(createPayload(), { signal });
      });
      response.data.itens.forEach((data) => {
        setDataTable(data.detail);
        setDataGraph(data.summarizedBySenderNumber);
        setTotalDispatchMessages(data.totalDispatchMessages);
        setTotalSentMessages(data.totalSentMessages);
        setTotalReceivedMessages(data.totalReceivedMessages);
        setTotalReadMessages(data.totalReadMessages);
        setTotalFailedMessages(data.totalFailedMessages);
        setTotalBillableMessages(data.totalBillableMessages);
      });
    } catch (error) {
      // 忽略请求取消的错误
      if (error.name !== 'AbortError') {
        console.error(error);
      }
    } finally {
      setIsLoadingGraph(false);
    }
  };

  fetchData();

  // 组件卸载或依赖更新时取消未完成的请求
  return () => controller.abort();
}, [periodFilter, originFilter, senderFilter, endDateTime, initialDateTime]);

关键说明

  • 指数退避:每次重试的延迟时间翻倍,避免短时间内大量请求冲击服务器,比如第1次等1秒、第2次等2秒、第3次等4秒。
  • 错误判断:需根据你的API错误响应结构调整判断逻辑(比如error.response?.status === 500),确保只重试服务器临时错误。
  • 请求取消:使用AbortController在组件卸载或依赖更新时取消未完成的请求,防止过时请求更新状态导致页面异常。

内容的提问来源于stack exchange,提问作者Guilherme Abel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 06:45:43