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

如何多次调用同一JS函数并等待上一次执行完成后再运行?

问题原因

你当前的写法无法顺序执行的核心原因是for循环是同步运行的,setTimeout属于异步宏任务,不会阻塞循环推进,代码运行时会瞬间触发所有rollSkins(你循环中写的rollDice属于命名笔误)调用,所有延时任务几乎同时启动,自然达不到“上一次执行完再跑下一次”的效果。
之前你用await没生效,基本是两个原因:一是被等待的函数没有返回Promise,await对普通同步函数、没做Promise包装的异步回调函数不会有等待效果;二是await没有写在async标记的函数内部,不符合语法规则。

正确实现方案

第一步:封装通用延时工具

把setTimeout包装成Promise形式,方便用await等待延时结束:

const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));

第二步:改造原有业务函数

给原有包含异步逻辑的函数加上async标记,内部用await等待延时和子调用执行完成,确保函数执行结束时,内部所有异步逻辑已经跑完:

async function rollSkins(results, rollN) {
    // 此处放原rollSkins函数里setTimeout之前的同步逻辑

    // 等待原逻辑里的500ms延时
    await wait(500);
    // 等待roll函数全流程执行完成
    await roll(results, rollN);
}

async function roll(results, rollN) {
    // 此处放原roll函数里setTimeout之前的同步逻辑

    // 等待原逻辑里的8500ms延时
    await wait(8500);
    // 此处放原roll函数setTimeout回调里的收尾逻辑
}

第三步:改造循环逻辑

把循环放在async函数内部,每次循环用await等待当前调用全流程结束后,再进入下一次循环:

// 用自执行async函数包裹业务逻辑,如果你已有外层async业务函数可以直接用
(async () => {
    // 注意循环变量用let声明,避免var带来的闭包变量污染问题
    for (let x = 0; x < rollsArr.length; x++) {
        await rollSkins(data.results, x);
        // 如果需要单次执行完成后额外等待数秒再启动下一次,在这里加等待即可,比如额外等2秒:
        // await wait(2000);
    }
    // 所有轮次执行完成后的后续逻辑写在这里
})();
注意事项
  • 不要用回调嵌套的方式实现顺序执行,轮次多了会形成回调地狱,维护成本极高
  • 循环变量必须用let声明,如果你用var,所有异步逻辑拿到的x都会是循环结束后的最终值,导致索引错误
  • 所有需要等待异步结果的函数,都要确保返回Promise,否则await不会按预期等待

内容的提问来源于stack exchange,提问作者Erik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 16:15:53