这是一个简单的html& javascript:当我点击“开始”按钮时,计数器启动,显示的数字递增,然后当我再次点击“开始”时,计数器重置并重新开始。 (这只是setTimeout
的一种练习,我不打算将其用作任何东西。)起初我忘了停止主循环并且每次点击按钮时都运行另一个主循环,这导致加速计数后重复点击。我看到了这个问题(javascript - How to stop a setTimeout loop?),并设法让它发挥作用。
然后我稍微更改了javascript。我认为这些代码几乎是相同的,但它不是 - 它不再起作用,多个mainLoop似乎在点击之后运行。我的问题:为什么这些不相同?后者为什么不起作用?
工作代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div>
<pre id="start" style="background-color:green; width:70px; text-align:center;">Start</pre>
<pre id="count"></pre>
</div>
<script src="main.js"></script>
</body>
</html>
main.js
var counter = 0;
var timer;
function mainLoop(){
counter++;
document.getElementById("count").innerHTML=counter;
timer = setTimeout(mainLoop,100);
}
function start(){
if (timer){
// stop mainLoop that is currently running.
clearTimeout(timer);
}
// and start again.
counter = 0;
mainLoop();
}
document.getElementById("start").addEventListener("click",start);
然后我改变了:
var counter = 0;
var timer;
function mainLoop(){
counter++;
document.getElementById("count").innerHTML=counter;
return setTimeout(mainLoop,100); // changed here
}
function start(){
if (timer){
clearTimeout(timer);
}
counter = 0;
timer = mainLoop(); // and here
}
document.getElementById("start").addEventListener("click",start);
答案 0 :(得分:2)
mainLoop 是循环自身,没有设置计时器这就是原因。
每次 setTimeout 都会获得一个新值,而如果您不更新它,则会停止旧的计时器。
您可能需要查看 setInterval(),而不需要重复创建Timer。
答案 1 :(得分:1)
您的代码将在返回值时第一次调用mainLoop
时运行。第二次调用时,它从setTimeout
调用,这意味着返回的值(新超时的值)将丢失。
当您尝试清除超时时,您尝试使用从第一次调用获得的值清除它,这是在任何情况下都会传递的超时,而不是当前超时值。
尝试在timer
中设置mainLoop
。
答案 2 :(得分:1)
执行clearTimeout(计时器) 在设置timer = mainLoop();
之前我也相信timer = mainloop()只是再次运行mainLoop函数timer只是超时函数..
它看起来像是你使用setTimeout作为间隔,也许你应该看看这个......
答案 3 :(得分:1)
您获得多个mainLoop
的原因是因为在mainLoop
中,您告诉它每100毫秒调用一次。然后它会将setTimeout
返回给自己,而不是将其返回start
方法。
所以你最终不止一次调用setTimeout,但你不存储返回值,你需要传递给clearTimeout来取消循环。
您可以做的事情如下:
function mainLoop() {
counter++;
document.getElementById("count").innerHTML=counter;
}
function start() {
if (timer){
clearTimeout(timer);
timer = undefined;
counter = 0;
} else {
timer = setInterval(mainLoop(), 100); // Set interval calls it every 100 milliseconds until it is cancelled
}
document.getElementById("start").addEventListener("click", start, false);