如何实现延迟后递归调用函数?现有递归延迟逻辑失效求解
问题分析与解决方法
你的代码里setTimeout(await checkReady(value - 1), 5000);是导致间隔不生效的核心原因:
await checkReady(value - 1)会立即执行这个异步函数,而非作为定时器的回调等待执行- 定时器实际收到的第一个参数是
checkReady执行后的返回值(undefined),相当于定时器到期后无操作,但递归调用已经提前触发,完全没起到5秒等待的作用
下面是两种正确的实现方式:
方法一:修正setTimeout的回调写法
把递归调用用箭头函数包裹后传给setTimeout,确保只有定时器到期后才执行下一次检查:
async isReady(ID) { try { const checkReady = async (value) => { console.log('checkReady = ' + value); if (value > 0) { let response = await client.get(`/user/account/isReady/${ID}`); let ready = response.data; if (ready) { this.Ready = true; return; } // 用箭头函数包裹,确保5秒后才触发下一次检查 setTimeout(() => checkReady(value - 1), 5000); } } await checkReady(10); } catch (e) { console.error(e); } }
注意:这种写法里await checkReady(10)不会等待所有递归完成(第一次checkReady执行到setTimeout就会返回),如果需要isReady函数直到检查结束才返回,建议用方法二。
方法二:用Promise封装延迟(推荐,可读性更强)
封装一个延迟函数,通过await等待5秒后再递归,让异步逻辑更线性直观:
async isReady(ID) { try { // 封装延迟函数 const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms)); const checkReady = async (value) => { console.log('checkReady = ' + value); if (value <= 0) return; let response = await client.get(`/user/account/isReady/${ID}`); let ready = response.data; if (ready) { this.Ready = true; return; } // 等待5秒后再执行下一次检查 await delay(5000); await checkReady(value - 1); } await checkReady(10); } catch (e) { console.error(e); } }
这种写法中,整个checkReady的递归链通过await串联,await checkReady(10)会等待所有检查完成(直到返回true或次数耗尽),更符合async函数的预期行为。
内容的提问来源于stack exchange,提问作者Jyina
相关产品推荐
相关产品推荐

