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

Jest v28.1.3递归异步函数无需done的实现方案求助

解决Jest中done回调与Promise冲突的问题

你遇到的错误提示很明确:

Test functions cannot both take a 'done' callback and return something. Either use a 'done' callback, or return a promise.
Returned value: Promise {}

问题出在beforeAll既是async函数(会自动返回Promise),又同时接受done参数,Jest不允许这种混合写法。而你的iAmReady函数依赖done来通知初始化完成,直接去掉done又会导致测试先执行、初始化后完成,核心解决思路是把iAmReady改造成纯Promise风格的函数,彻底抛弃done回调。

改造iAmReady函数

将原来依赖done的递归异步函数,改成返回Promise的形式,用await处理延迟和重试逻辑:

let attempts = 0;
const iAmReady = async () => {
  try {
    // 尝试连接服务
    await request.get({ uri: 'http://localhost:7575/ready' });
  } catch (err) {
    attempts += 1;
    if (attempts > 10) {
      throw new Error('Failed to connect.');
    }
    // 等待500ms后重试
    await new Promise(resolve => setTimeout(resolve, 500));
    // 递归调用自身继续尝试
    await iAmReady();
  }
};

修改beforeAll调用

现在beforeAll只需要await这个Promise即可,不需要done参数:

beforeAll(async () => {
  await iAmReady();
});

it('test', () => {
  // test stuff
});

为什么这样可行?

  1. 改造后的iAmReady全程用Promise管理异步流程,Jest可以通过await正确等待它执行完成,确保初始化完成后再运行测试。
  2. 去掉done参数后,beforeAll作为async函数返回的Promise,和Jest的异步处理逻辑完全兼容,不会再触发冲突错误。
  3. 用await new Promise(...)替代原来的setTimeout,解决了原代码中setTimeout内部异步操作无法被Jest追踪的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 03:45:54