重复点击start按钮致计数器加速、stop失效的原因及解决方法
问题产生原因
问题核心出在定时器创建逻辑没有做重复调用拦截:
- 每点击一次start按钮,
startTimer函数就会执行一次setInterval,生成一个全新的并行定时器,同时把新定时器的ID覆盖赋值给myCounter变量。多次点击就会同时存在多个独立运行的定时器,每个定时器都会按200ms的间隔触发计数,直接导致计数速度异常升高。 - 早先创建的旧定时器ID因为被新值覆盖,已经无法被
clearInterval方法定位到,点击stop按钮时只能清除最后一次创建的定时器,残留的旧定时器会持续运行,表现为stop按钮失效无法停止计数。
解决方案
新增定时器运行状态标记,在启动定时器前先校验当前运行状态,若定时器已经在运行则直接拦截启动逻辑,避免重复创建定时器。修正后完整代码如下:
<button id="startBtn" onclick="startTimer()">Start</button> <button id="stopBtn" onclick="stopTimer()">Stop</button> <h2 id="timer"></h2> <script> let myCounter // 标记定时器是否处于运行状态 let isRunning = false; function startTimer() { // 已运行时直接拦截重复点击 if (isRunning) return; isRunning = true; myCounter = setInterval(counter, 200); } function stopTimer() { clearInterval(myCounter); // 停止后重置状态,允许下次正常启动 isRunning = false; } let i = 0; function counter() { document.getElementById("timer").innerHTML = i++; } </script>
逻辑说明:
- 首次点击start时,运行状态为未启动,正常创建定时器,同时将状态标记为运行中
- 后续重复误触start时,检测到运行中状态会直接终止函数执行,不会生成新的并行定时器,计数速度不会异常变化
- 点击stop清除定时器的同时重置运行状态,下次点击start可以正常重新启动计数
内容的提问来源于stack exchange,提问作者Aptia Rahgozar
相关产品推荐
相关产品推荐

