返回setTimeout以后停止不能满足我的期望?

时间:2014-05-14 09:16:04

标签: javascript settimeout

这是一个简单的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);

4 个答案:

答案 0 :(得分:2)

mainLoop 是循环自身,没有设置计时器这就是原因。

每次 setTimeout 都会获得一个新值,而如果您不更新它,则会停止旧的计时器。

您可能需要查看 setInterval(),而不需要重复创建Timer。

答案 1 :(得分:1)

您的代码将在返回值时第一次调用mainLoop时运行。第二次调用时,它从setTimeout调用,这意味着返回的值(新超时的值)将丢失。

当您尝试清除超时时,您尝试使用从第一次调用获得的值清除它,这是在任何情况下都会传递的超时,而不是当前超时值。

尝试在timer中设置mainLoop

答案 2 :(得分:1)

执行clearTimeout(计时器) 在设置timer = mainLoop();

之前

我也相信timer = mainloop()只是再次运行mainLoop函数timer只是超时函数..

它看起来像是你使用setTimeout作为间隔,也许你应该看看这个......

jQuery setInterval()

答案 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);