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

如何用非递归方式实现带重试参数的Fetch API请求函数?

把递归的Fetch重试函数改成非递归形式

嘿,这个需求很常见!递归实现重试虽然简单,但改成非递归会让逻辑更直观可控(虽然这里用了setTimeout不会导致栈溢出,但非递归写法可读性更强)。我给你两种实用的非递归方案:

方案一:用Async/Await + 循环(最直观)

这种方式利用async/await的同步写法配合循环,代码非常容易理解:

const fetchRetry = async (url, delay, limit, fetchOptions = {}) => {
  let attemptCount = 0;
  
  while (attemptCount <= limit) {
    try {
      const response = await fetch(url, fetchOptions);
      
      // 注意:Fetch API只有网络错误才会reject,HTTP错误(如4xx/5xx)会resolve
      // 这里可以根据你的需求决定是否要把HTTP错误也纳入重试范围
      if (!response.ok) {
        throw new Error(`请求失败,状态码:${response.status}`);
      }
      
      return response; // 成功则直接返回响应
    } catch (error) {
      if (attemptCount === limit) {
        // 达到重试上限,抛出错误给调用方处理
        throw error;
      }
      
      // 等待指定延迟后,进行下一次尝试
      await new Promise(resolve => setTimeout(resolve, delay));
      attemptCount++;
    }
  }
};

说明:

  • 每次尝试失败后,只要还没到重试次数上限,就等待delay毫秒后继续循环
  • 如果你不需要对HTTP错误进行重试,可以去掉!response.ok的判断逻辑
  • 调用方式和原来一致,返回的仍是Promise:fetchRetry('/api/data', 1000, 3).then(res => ...).catch(err => ...)

方案二:用Promise链式循环(纯Promise风格)

如果你更习惯纯Promise写法,不想依赖async/await,可以通过循环构建Promise链实现非递归重试:

const fetchRetry = (url, delay, limit, fetchOptions = {}) => {
  // 初始化一个被拒绝的Promise,触发第一次尝试
  let retryPromise = Promise.reject();
  
  for (let i = 0; i <= limit; i++) {
    retryPromise = retryPromise
      // 上一次失败后,发起新的请求
      .catch(() => fetch(url, fetchOptions))
      .then(response => {
        if (!response.ok) {
          throw new Error(`请求失败,状态码:${response.status}`);
        }
        return response;
      })
      .catch(error => {
        // 如果是最后一次尝试失败,直接抛出错误
        if (i === limit) {
          throw error;
        }
        // 否则等待延迟后,让Promise链继续执行下一次尝试
        return new Promise(resolve => setTimeout(resolve, delay));
      });
  }
  
  return retryPromise;
};

说明:

  • 通过循环逐步构建Promise链,每一轮循环对应一次重试尝试
  • 同样处理了HTTP错误的情况,你可以根据需求调整
  • 这种方式不需要依赖async/await,适合一些对语法有限制的环境

这两种方案都完全避免了递归调用,逻辑清晰且容易维护,你可以根据自己的代码风格选择合适的版本~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:32:59