JavaScript秒表多次点击启动加速问题及导师代码原理咨询
多次点击启动按钮秒表加速的原因及解决方案原理
我跟着教程用JavaScript做了个秒表,把导师写的一段代码注释掉后,多次点启动按钮,秒表走得比正常快;恢复那段代码就正常了。想搞懂这段代码解决问题的原理,下面是我修改后的代码:
let [hours, minutes, seconds] = [0, 0, 0]; let displayTime = document.getElementById("displayTime"); let timer = null; function stopWatch() { seconds++; if (seconds == 60) { seconds = 0; minutes++; if (minutes == 60) { minutes = 0; hours++; } } let h = hours < 10 ? "0" + hours : hours; let m = minutes < 10 ? "0" + minutes : minutes; let s = seconds < 10 ? "0" + seconds : seconds; displayTime.innerHTML = h + ":" + m + ":" + s; } function watchStart() { // if (timer!== null){ // clearInterval(timer); // } timer = setInterval(stopWatch, 1000); } function watchStop(){ clearInterval(timer); } function watchReset(){ clearInterval(timer); [hours, minutes, seconds] = [0, 0, 0]; displayTime.innerHTML = "00:00:00"; }
<div class="stopwatch"> <h1 id="displayTime">00:00:00</h1> <div class="buttons"> <button onclick="watchStop()">Stop</button> <button onclick="watchStart()">Start</button> <button onclick="watchReset()">Reset</button> </div> </div>
问题根源
每次点启动按钮调用watchStart()时,要是不先清除已有的定时器,新的setInterval会和旧定时器同时跑起来。比如第一次点启动,开了个每秒让seconds加1的定时器;第二次再点,又开一个新的,现在两个定时器每秒各加1,秒表自然翻倍快。点得越多,同时运行的定时器越多,走速就越快。
那段注释代码的作用
被你注释的这段代码是核心解决方案:
if (timer!== null){ clearInterval(timer); }
逻辑拆解:
timer变量存的是setInterval返回的定时器ID,初始值是null- 每次启动前先检查:如果
timer不是null,说明已经有正在运行的定时器,就用clearInterval(timer)把它停掉 - 清掉旧的之后再创建新定时器并赋值给
timer,这样就保证同一时间只有一个定时器在工作,不管点多少次启动,都不会出现多个定时器同时累加秒数的情况
额外补充
setInterval每次调用都会返回唯一的ID,clearInterval就是靠这个ID来精准停止对应的定时器- 点击
watchStop()或watchReset()时,虽然调用了clearInterval(timer)停止定时器,但timer变量本身不会自动变回null,所以下次启动时必须先检查并清除,避免旧定时器残留运行
内容的提问来源于stack exchange,提问作者noob star
相关产品推荐
相关产品推荐

