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

含条件判断与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))
    })
}

问题分析与修复

核心问题点

  1. 递归Promise未链式传递:当n > 0时,recursiveInterval创建的新Promise没有被resolve——递归调用返回的Promise没有和当前Promise关联,导致上层Promise一直处于pending状态,无法触发then回调。
  2. 冗余的Promise包装:projectMGR里没必要额外包裹一层新Promise,recursiveInterval本身就返回Promise,直接调用即可。
  3. 无效的代码逻辑: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 09:15:35