含条件判断与setTimeout的递归函数Promise未解决问题求助
问题描述
尝试实现一个包含递归函数、setTimeout和Promise的代码片段但未成功。递归与setTimeout功能正常,但Promise似乎无法resolve,因为projectMGR()中配置的thenable没有输出对应消息。
已尝试的解决方案
已深入研究执行上下文、Promise的各种resolve方法、MDN相关练习及Stack Overflow解决方案,但均未成功。此外,还尝试将递归函数调用包裹在async中(当前已配置),以及在全局执行上下文(GEC)中直接配置Promise。
输出对比
| 预期输出 | 实际输出 |
|---|---|
| 10 more to go... | 10 more to go... |
| 9 more to go... | 9 more to go... |
| 8 more to go... | 8 more to go... |
| 7 more to go... | 7 more to go... |
| 6 more to go... | 6 more to go... |
| 5 more to go... | 5 more to go... |
| 4 more to go... | 4 more to go.. |
| 3 more to go... | 3 more to go... |
| 2 more to go... | 2 more to go... |
| 1 more to go... | 1 more to go... |
| Finished just in time for Happy Hour!🍻. |
原始代码片段
projectMGR(); const prom = []; async function recursiveInterval(arr, n, ms = 1000) { return new Promise((resolve) => { setTimeout (() => { if (n === 0) { resolve(`Finished just in time for Happy Hour!🍻. `) } else { console.log(`${n} more to go...`); recursiveInterval(arr, n - 1) - arr[n - 1]; }; },ms); } ); }; async function projectMGR() { let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; let n = arr.length; new Promise(() => { recursiveInterval(arr, n) .then((resolve) => console.log(resolve)) }) }
问题分析与修复
核心问题点
- 递归Promise未链式传递:当
n > 0时,recursiveInterval创建的新Promise没有被resolve——递归调用返回的Promise没有和当前Promise关联,导致上层Promise一直处于pending状态,无法触发then回调。 - 冗余的Promise包装:
projectMGR里没必要额外包裹一层新Promise,recursiveInterval本身就返回Promise,直接调用即可。 - 无效的代码逻辑:
recursiveInterval(arr, n - 1) - arr[n - 1];中的减号操作完全多余,且没有处理递归返回的Promise。
修复后的代码
projectMGR(); async function recursiveInterval(arr, n, ms = 1000) { return new Promise((resolve) => { setTimeout(() => { if (n === 0) { resolve(`Finished just in time for Happy Hour!🍻. `); } else { console.log(`${n} more to go...`); // 递归调用后,通过其then方法来resolve当前Promise recursiveInterval(arr, n - 1).then(resolve); } }, ms); }); } async function projectMGR() { let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; let n = arr.length; // 直接调用recursiveInterval,无需额外Promise包装 recursiveInterval(arr, n).then((msg) => console.log(msg)); }
更简洁的写法(利用async/await)
因为recursiveInterval已经是async函数,还可以简化成:
projectMGR(); async function recursiveInterval(arr, n, ms = 1000) { await new Promise(resolve => setTimeout(resolve, ms)); if (n === 0) { return `Finished just in time for Happy Hour!🍻. `; } else { console.log(`${n} more to go...`); return recursiveInterval(arr, n - 1); } } async function projectMGR() { let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; let n = arr.length; const msg = await recursiveInterval(arr, n); console.log(msg); }
这样修改后,递归的Promise会正确链式传递,最终触发resolve,输出预期的完成消息。
内容的提问来源于stack exchange,提问作者Private Emblem
相关产品推荐
相关产品推荐

