async/await递归无法在主函数中完成Promise解析问题求助
解决async/await递归中Promise无法resolve的问题
咱来瞅瞅你代码里的问题——核心是recursion函数的写法踩了两个坑,导致整个Promise链一直处于pending状态,main函数里的await永远等不到最终结果:
问题拆解
- 冗余的手动Promise嵌套:
recursion本身就是async函数,async函数会自动把返回值包装成Promise,完全没必要再手动return new Promise(...),这种嵌套很容易遗漏resolve逻辑。 - 递归分支未resolve外层Promise:在
else分支里,你调用了await recursion(i),但外层那个手动创建的Promise从来没被resolve(除了i=0的情况)。举个例子:当i=1时,递归调用recursion(0)会resolve,但recursion(1)自己的Promise没被resolve,导致recursion(2)的await拿不到结果,层层往上,最终main里的await recursion(3)一直卡着。
修正方案
方案1:利用async函数的天然Promise特性(推荐)
直接去掉手动包裹的Promise,让async函数自己处理Promise返回,代码更简洁不易错:
async function delay(ms) { return await new Promise(resolve => setTimeout(resolve, ms)) } async function recursion(i) { if (i == 0) { console.log(`i == 0`) return i; // async函数中return的值会自动作为Promise的resolve结果 } else { console.log(`i = ${i}. Wait 2 seconds...`) i-- await delay(2000) return recursion(i); // 返回递归的Promise,让上层await能获取结果 } } async function main() { let i = await recursion(3) console.log(`END OF RECURSION`) console.log(`i => ${i}`) } main()
方案2:保留手动Promise(不推荐,但可以作为理解参考)
如果非要手动创建Promise,必须确保每个分支都调用resolve,把递归的结果传递出去:
async function delay(ms) { return await new Promise(resolve => setTimeout(resolve, ms)) } async function recursion(i) { return new Promise(async (resolve, reject) => { if (i == 0) { console.log(`i == 0`) resolve(i) } else { console.log(`i = ${i}. Wait 2 seconds...`) i-- await delay(2000) const result = await recursion(i) resolve(result); // 必须resolve递归结果,否则外层Promise永远pending } }) } async function main() { let i = await recursion(3) console.log(`END OF RECURSION`) console.log(`i => ${i}`) } main()
运行修正后的代码,你就能看到END OF RECURSION和i => 0的输出啦~
内容的提问来源于stack exchange,提问作者Egeniy Ostrovskiy




