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 });
为什么这样可行?
- 改造后的
iAmReady全程用Promise管理异步流程,Jest可以通过await正确等待它执行完成,确保初始化完成后再运行测试。 - 去掉
done参数后,beforeAll作为async函数返回的Promise,和Jest的异步处理逻辑完全兼容,不会再触发冲突错误。 - 用
await new Promise(...)替代原来的setTimeout,解决了原代码中setTimeout内部异步操作无法被Jest追踪的问题。
内容的提问来源于stack exchange,提问作者theJuls
相关产品推荐
相关产品推荐

