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

如何在TypeScript中实现类型安全的通用限流重试处理函数

类型安全的429限流重试工具实现方案

核心修改点

  • 引入泛型 P extends any[] 约束函数入参类型,替换原有不安全的any参数声明
  • 引入泛型 T 约束异步函数的返回值类型,实现返回值自动类型推导
  • 补充错误类型守卫,避免catch块内滥用any类型
  • 调用时无需手动声明泛型,即可获得完整的参数校验和返回值类型提示

完整实现代码

首先补充sleep函数的基础定义(如果已有可忽略):

const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms))

最终的类型安全重试工具实现:

// 通用HTTP错误类型定义,如果你使用Axios也可以直接替换为AxiosError
type HttpError = {
  response: {
    status: number
  }
}

// 类型守卫:安全判断错误是否为带response.status的HTTP请求错误
function isHttpError(err: unknown): err is HttpError {
  return !!err 
    && typeof err === 'object' 
    && 'response' in err 
    && !!(err as HttpError).response 
    && typeof (err as HttpError).response === 'object'
    && 'status' in (err as HttpError).response 
    && typeof (err as HttpError).response.status === 'number'
}

// 泛型P约束入参类型,泛型T约束返回值类型
async function throttleHandler<P extends any[], T>(
  promiseFunction: (...args: P) => Promise<T>,
  ...args: P
): Promise<T> {
  do {
    try {
      return await promiseFunction(...args)
    } catch (err: unknown) {
      if (isHttpError(err) && err.response.status === 429) {
        await sleep(300)
        console.log('Throttle happened, sleeping for 300ms')
      } else {
        throw err
      }
    }
  } while (true)
}

使用示例

调用时会自动匹配传入API的参数类型和返回值类型,参数传错会直接触发TS类型报错,返回值无需额外类型断言:

// 示例API函数定义
const myApi = (arg1: string, arg2: number, arg3: boolean): Promise<{assets: string[]}> => {
  // 你的实际API逻辑
  return Promise.resolve({assets: ['img1.png', 'img2.png']})
}

// 自动推导返回值类型为 {assets: string[]},参数会自动校验类型
const res = await throttleHandler(myApi, 'test_param', 123, true)

可选优化(支持自定义配置)

如果需要灵活调整重试间隔、最大重试次数,可扩展为带配置项的版本:

async function throttleHandler<P extends any[], T>(
  promiseFunction: (...args: P) => Promise<T>,
  options: {retryDelay?: number, maxRetries?: number} = {},
  ...args: P
): Promise<T> {
  const {retryDelay = 300, maxRetries = Infinity} = options
  let retryCount = 0
  do {
    try {
      return await promiseFunction(...args)
    } catch (err: unknown) {
      if (isHttpError(err) && err.response.status === 429 && retryCount < maxRetries) {
        retryCount++
        await sleep(retryDelay)
        console.log(`Throttle happened, retry ${retryCount}/${maxRetries}, sleeping for ${retryDelay}ms`)
      } else {
        throw err
      }
    }
  } while (true)
}

内容的提问来源于stack exchange,提问作者Derviş Kayımbaşıoğlu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 19:45:04