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

两个独立Timer异常:点击启动按钮后同时运行,求排查解决

双计时器同步启动问题排查与修复

问题描述

编写了两个独立计时器,但点击任意一个启动按钮时,两个计时器都会同时开始运行,尝试条件判断无效,需排查修复。

原代码

JavaScript

const res = document.getElementById('res'),
  btnStart = document.getElementById('start'),
  btnStop = document.getElementById('stop');

const res1 = document.getElementById('res1'),
  btnStart1 = document.getElementById('start1'),
  btnStop1 = document.getElementById('stop1');


function getCounter(el, startBtn, stopBtn) {
  let sec = 0;
  let min = 0;
  let hours = 0;
  let interval;
  let isAvtive = false;

  function updateCounter() {
    sec++;
    if (sec === 60) {
      min++;
      sec = 0;
    }
    if (min === 60) {
      hours++;
      min = 0;
    }
    if (hours === 24) {
      hours = 0;
    }
    el.textContent = sec;
    if (btnStart) {
      res.textContent = `${hours.toString().padStart(2,0)}:${min.toString().padStart(2,0)}:${sec.toString().padStart(2,0)}`;
    }
    if (btnStart1) {
      res1.textContent = `${hours.toString().padStart(2,0)}:${min.toString().padStart(2,0)}:${sec.toString().padStart(2,0)}`;
    }

  }

  startBtn.addEventListener('click', function() {
    if (btnStart)
      interval = setInterval(updateCounter, 1000);


  });
  stopBtn.addEventListener("click", function() {

    if (interval) {
      clearInterval(interval)
      interval = null;

    }
  })


}


getCounter(res, btnStart, btnStop);
getCounter(res1, btnStart1, btnStop1);

HTML

<input type="button" value="start" id="start" />
<input type="button" value="stop" id="stop" />
<span id="res"></span>

<br/>

<input type="button" value="start1" id="start1" />
<input type="button" value="stop1" id="stop1" />
<span id="res1"></span>

问题排查

  1. 全局DOM硬编码干扰:updateCounter函数直接操作全局的res和res1元素,导致每个计时器的回调都会同时修改两个显示区域,造成"同步运行"的错觉。
  2. 启动逻辑判断错误:启动按钮的判断使用全局变量btnStart,而非当前实例的startBtn参数,导致两个计时器实例都会执行同一启动逻辑。
  3. 未控制重复启动:定义了isAvtive状态但未使用,无法防止多次点击启动按钮创建叠加定时器。

修复方案

修改getCounter函数,让每个计时器实例完全独立,仅依赖传入参数和自身内部状态:

function getCounter(el, startBtn, stopBtn) {
  let sec = 0;
  let min = 0;
  let hours = 0;
  let interval = null;
  let isActive = false;

  function updateCounter() {
    sec++;
    if (sec === 60) {
      min++;
      sec = 0;
    }
    if (min === 60) {
      hours++;
      min = 0;
    }
    if (hours === 24) {
      hours = 0;
    }
    // 仅更新当前实例对应的显示元素
    el.textContent = `${hours.toString().padStart(2,0)}:${min.toString().padStart(2,0)}:${sec.toString().padStart(2,0)}`;
  }

  startBtn.addEventListener('click', function() {
    // 防止重复启动
    if (!isActive) {
      isActive = true;
      interval = setInterval(updateCounter, 1000);
    }
  });

  stopBtn.addEventListener("click", function() {
    if (interval) {
      clearInterval(interval);
      interval = null;
      isActive = false;
    }
  });
}

// 初始化两个独立计时器
getCounter(document.getElementById('res'), document.getElementById('start'), document.getElementById('stop'));
getCounter(document.getElementById('res1'), document.getElementById('start1'), document.getElementById('stop1'));

修改说明

  • 移除全局DOM变量依赖,仅通过传入的el参数更新当前计时器的显示内容
  • 使用isActive状态控制计时器启停,避免多次点击启动按钮创建叠加定时器
  • 每个计时器实例的sec、min、hours、interval均为独立局部变量,互相无干扰
  • 简化启动逻辑,基于当前实例状态处理,不再依赖全局按钮变量判断

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 09:40:35