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

JavaScript中如何确保repeatPatternColor的所有动画执行完成后再调用generateColor?

JavaScript中如何确保repeatPatternColor的所有动画执行完成后再调用generateColor?

嘿,我明白你的困扰啦!你现在遇到的问题核心在于Promise的resolve时机不对——你的repeatPatternColor和generateColor里的Promise都提前完成了,根本没等里面的动画定时器执行完,所以await自然起不到等待的作用。咱们一步步来解决:

首先修复repeatPatternColor的问题

你现在的代码里,for循环一结束就立刻调用了resolve(),但循环里的所有setTimeout都是异步任务,循环结束时这些定时器甚至还没开始执行呢!所以Promise直接标记为完成,await也就跳过等待,直接去执行generateColor了。

推荐用更直观的async/await写法来封装循环内的异步操作,逻辑清晰不容易出错:

// 先封装一个通用的等待函数,把setTimeout转成Promise
function wait(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function repeatPatternColor(pattern) {
    for (let i = 0; i < pattern.length; i++) {
        // 等待当前迭代的初始延迟
        await wait((i + 1) * delayMileSec);
        const color = pattern[i];
        const singleCol = document.getElementById(color);
        
        // 添加高亮类,等待动画时长
        singleCol.classList.add(`${color}-light`);
        await wait(delayMileSec);
        
        // 移除高亮类,完成当前迭代的动画
        singleCol.classList.remove(`${color}-light`);
        console.log(color);
    }
}

这样每一次循环的动画都会按顺序执行,整个函数会在所有循环的动画都完成后才结束,await就能正确等待了。

然后调整generateColor的resolve时机

你这里同样犯了Promise提前resolve的错误——resolve()写在了setTimeout外面,导致Promise在动画还没结束时就完成了。我们需要把resolve()移到setTimeout的回调里,确保动画完成后才标记Promise完成:

function generateColor() {
    return new Promise((resolve) => {
        disableDivs();
        const randomNum = Math.floor(Math.random() * 4);
        const id = color[randomNum].id;
        pattern.push(id);
        const singleCol = document.getElementById(id);
        singleCol.classList.add(`${id}-light`);
        setTimeout(function () {
            singleCol.classList.remove(`${id}-light`);
            enableDivs();
            console.log("Pattern: " + pattern);
            resolve(); // 动画全部完成后再resolve
        }, 1000);
    });
}

调用部分无需修改

你原来的fnAsync写法是对的,只要上面两个函数的Promise处理正确,await就会严格按顺序等待:

async function fnAsync() {
    await repeatPatternColor(pattern);
    await generateColor();
}

let response = fnAsync();

这样修改后,generateColor就会等到repeatPatternColor里的所有动画都执行完成后才开始运行啦!

备注:内容来源于stack exchange,提问作者Arian Gorani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 16:58:02