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

如何在JavaScript中同时运行多个setTimeout并解决循环变量取值异常问题

问题根因
  • 代码中var声明的变量为函数/全局作用域,全循环共用同一个i和amt实例,循环执行结束后i最终值为10,所有异步触发的checktime引用的都是最终的i值,因此输出的i全为10。
  • 不同循环的amt变量没有独立隔离,多个checktime的计数逻辑会互相冲突,无法实现每个i对应独立计数的需求。
实现方案

核心解决思路是为每次循环创建独立作用域,隔离每个循环的i和amt变量,两种常见实现方式如下:

// 方案1:ES6+ 用let创建块级作用域
for (let i = 0; i < 10; i++) {
  let amt = 0;
  function checktime() {
    console.log(`${amt} / ${i}`);
    amt++;
    if (amt <= 5) {
      setTimeout(checktime, 3000);
    }
  }
  checktime();
}

// 方案2:ES5 用IIFE(立即执行函数)创建独立作用域
for (var i = 0; i < 10; i++) {
  (function(currentI) {
    var amt = 0;
    function checktime() {
      console.log(amt + " / " + currentI);
      amt++;
      if (amt <= 5) {
        setTimeout(checktime, 3000);
      }
    }
    checktime();
  })(i);
}

方案说明

  • 方案1中let支持块级作用域,每次循环都会生成独立的i和amt实例,每个checktime会绑定当前循环的变量,互不干扰。
  • 方案2通过立即执行函数为每次循环创建独立的函数作用域,将当前i作为参数传入保存,内部维护独立的计数变量,可兼容旧版本JS运行环境。
  • 两种方案均可实现需求:首轮立即输出0/0到0/9的全部内容,之后每3秒各i对应的计数独立自增,直到输出到5/9后停止。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 03:00:03