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

TypeScript通用失败Promise重试包装器修复及优化咨询

修复后的通用Promise重试包装器

原包装器的核心错误点:

  • 参数传递错误:调用目标函数fn时使用fn(args),args是数组会被作为单个参数传入,导致目标函数参数不匹配直接触发reject,正确做法是用扩展运算符fn(...args)展开数组为单个参数。
  • 递归调用错误:递归时误用了不存在的this.errorWrapper,应直接调用当前函数promiseRepeatWrapper,且传递参数时需用...args保持参数展开,避免数组被当作单个参数传递。
  • this指向冗余:普通函数中的this在全局调用场景下无意义,直接调用函数即可,无需依赖this。

修复后的代码:

// 补充sleep函数实现(原代码中未给出,需确保存在)
function sleep(ms: number) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

function promiseRepeatWrapper(fn: (...args: any[]) => Promise<any>, n: number = 0, ...args: any[]) {
  return new Promise((resolve) => {
    fn(...args).then((r) => {
      resolve(r);
    }).catch(() => {
      if (n < 3) {
        console.log("Partial error: " + n);
        sleep(1000).then(() => {
          resolve(promiseRepeatWrapper(fn, n + 1, ...args));
        });
      } else {
        resolve(undefined);
      }
    });
  });
}
Promise重试模式的错误处理改进建议
  • 保留错误详情:当前实现忽略了错误具体信息,建议在catch中捕获错误对象并记录,方便排查问题:

    .catch((error) => {
      console.log(`Partial error ${n}:`, error);
      // 后续重试逻辑
    })
    
  • 配置化重试规则:将重试次数、间隔时间改为可配置参数,提升包装器通用性:

    function promiseRepeatWrapper(
      fn: (...args: any[]) => Promise<any>,
      maxRetries: number = 3,
      retryDelay: number = 1000,
      n: number = 0,
      ...args: any[]
    ) {
      // 逻辑中用maxRetries代替硬编码的3,retryDelay代替1000
    }
    
  • 指数退避策略:对不稳定API采用指数退避(如第1次等1秒,第2次2秒,第3次4秒),避免短时间重复请求加重服务端压力:

    const delay = retryDelay * Math.pow(2, n);
    sleep(delay).then(/* 重试逻辑 */);
    
  • 过滤可重试错误:并非所有错误都适合重试(如参数错误、401权限错误),允许传入错误过滤函数,仅对特定错误重试:

    function promiseRepeatWrapper(
      fn: (...args: any[]) => Promise<any>,
      shouldRetry: (error: any) => boolean = () => true,
      maxRetries: number = 3,
      retryDelay: number = 1000,
      n: number = 0,
      ...args: any[]
    ) {
      // catch中添加判断:
      if (n < maxRetries && shouldRetry(error)) {
        // 执行重试
      } else {
        resolve(undefined);
      }
    }
    
  • 用async/await简化代码:替代嵌套Promise,提升代码可读性:

    async function promiseRepeatWrapper(
      fn: (...args: any[]) => Promise<any>,
      maxRetries: number = 3,
      retryDelay: number = 1000,
      n: number = 0,
      ...args: any[]
    ) {
      try {
        const result = await fn(...args);
        return result;
      } catch (error) {
        if (n < maxRetries) {
          console.log(`Partial error ${n}:`, error);
          await sleep(retryDelay * Math.pow(2, n));
          return promiseRepeatWrapper(fn, maxRetries, retryDelay, n + 1, ...args);
        }
        return undefined;
      }
    }
    
  • 优化原fetchAPI的错误捕获:原fetchAPI中的同步try/catch无法捕获异步错误,应改为直接链式捕获:

    function fetchAPI(arg1: number, arg2: number, arg3: string) {
      return myFetchFunction(arg1, arg2, arg3).then((r: any) => {
        if (!r) {
          throw new Error("Error 01");
        }
        return r;
      }).catch(() => {
        throw new Error("Error 01");
      });
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 02:55:28