You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

闭包与计数器堆叠问题咨询:多timer实例致计数步长异常

问题原因分析与解决方案

嘿,这个问题的核心是变量作用域的问题,咱们一步步拆解来看:

为什么会出现“实例越多,每次递增数值越大”的现象?

你代码里的counter没有用var/let/const声明,这意味着它是一个全局变量——所有通过addTimer创建的定时器,都会共享同一个counter变量。

咱们理一理实际执行流程:

  • 第一次调用addTimer("#timerTag", "red", 1000):把全局counter设为0,启动一个定时器,每秒执行一次timeIt,每次执行都会让counter++。这时候只有一个定时器,所以每秒数值加1,显示正常。
  • 第二次调用addTimer("#tt", "blue", 1000):先把全局counter重置为0,再启动第二个定时器,这个定时器的timeIt同样操作全局的counter。现在每秒有两个定时器同时触发,每个都执行counter++,所以数值每次跳2。
  • 第三次调用后,三个定时器每秒各执行一次counter++,自然每次就加3了。

怎么修复这个问题?

只需要把counter变成addTimer函数的局部变量,让每个addTimer调用都拥有独立的counter,这样每个定时器的timeIt闭包捕获的都是自己专属的变量。修改后的代码如下:

function addTimer(elementID, cssColor, time){
  // 用let声明局部变量counter,每个addTimer调用都会创建独立的counter实例
  let counter = 0; 
  function timeIt(){
    $(elementID).text(counter);
    $(elementID).css("color", cssColor);
    counter ++;
  }
  setInterval(timeIt, time)
}

addTimer("#timerTag", "red", 1000)
addTimer("#tt", "blue", 1000)
addTimer("#ttt", "pink", 1000)

这样每个定时器都会维护自己的独立计数,互相不会干扰,每个实例都会每秒递增1啦~

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

火山引擎 最新活动