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

TypeScript报错:传入的Promise无调用签名,无法调用

问题原因及解决方案

核心问题

你给retry方法的promise参数定义的类型是Promise<any>,这表示它是一个Promise实例,但你在代码里却把它当成函数调用(promise())——Promise实例本身不具备调用能力,TypeScript因此提示“没有调用签名”。

实际场景中,重试逻辑需要每次重新执行异步操作,所以应该让调用者传入一个返回Promise的函数,而非直接传入Promise实例(否则第一次Promise完成后,重试时只会重复拿到已完成的结果,失去重试意义)。

修复步骤

  1. 修改promise参数的类型为() => Promise<any>,明确这是一个无参数、返回Promise的函数;
  2. (可选)把宽泛的Function类型替换为更明确的() => void来定义onRetry,提升类型安全性。

修正后的完整代码

export class ExponentialBackoffUtils {
    public static retry(promiseFn: () => Promise<any>, maxRetries: number, onRetry?: () => void) {
        function waitFor(milliseconds: number) {
            return new Promise((resolve) => setTimeout(resolve, milliseconds));
        }
        async function retryWithBackoff(retries: number) {
            try {
                if (retries > 0) {
                    const timeToWait = 2 ** retries * 1000;
                    await waitFor(timeToWait);
                }
                console.log('Retries: ', retries);
                // 移除测试用的强制抛出逻辑,实际使用时直接执行传入的异步函数
                // if (retries < 3) {
                //     throw new Error();
                // }
                return await promiseFn();
            } catch (e) {
                if (retries < maxRetries) {
                    onRetry?.(); // 用可选链简化条件判断
                    return retryWithBackoff(retries + 1);
                } else {
                    throw e;
                }
            }
        }

        return retryWithBackoff(0);
    }
}

额外说明

  • 将参数名改为promiseFn更直观,能清晰区分“返回Promise的函数”和“Promise实例”;
  • 原代码中if (retries < 3) throw new Error()是测试重试逻辑的临时代码,实际使用时记得移除,否则会强制触发3次重试才执行真实异步操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 08:18:35