【问题标题】:setInterval being skipped the first call and Clearinterval not stopping when called JavascriptsetInterval 在第一次调用时被跳过,并且 Clearinterval 在调用 Javascript 时没有停止
【发布时间】:2017-03-11 23:24:42
【问题描述】:

我正在尝试创建一个计时器,它每秒都会调用另一个函数。所以我在 for 循环中使用 setInterval。

在 for 循环的第一个循环中跳过了 setInterval。 不知道为什么。

另外, 当间隔低于零时,我有清除间隔的功能。当我在停止条件下打印消息时,会输出但会跳过 clearInterval。

function changesystem(lottery, maxroundtime, firstloop) {
  //loop through lottery numbers
  for (var keys in lottery) {
    var currentnum = lottery[keys].LotteryNum;
    console.log(currentnum);
    var currentclass = lottery[keys].ClassID;

    //console.log(currentclass);

    //display values
    $('#CurrentNumber').text(currentnum);
    $('#CurrentClass').text(currentclass);

    //change progress bar
    //every second until reaches max round time

    // var loopcontrol = maxroundtime;
    var loopcontrol = 5;
    var timerloop = setInterval(function() {

      console.log(loopcontrol);

      //changetime(maxroundtime,firstloop);
      loopcontrol--;
      //firstloop=1;  

    }, 1000);

    if (loopcontrol < 0) {
      clearInterval(timerloop);
    }
  }

Visual Example

【问题讨论】:

  • 你的 var timerloop 被你的 for 循环的每次迭代破坏
  • 缩进也被破坏了...
  • 我想你可能会认为setInterval 会以某种方式等待几秒钟过去,但事实并非如此,for 循环将立即遍历所有迭代,并创建了同样多的 @987654326 @计时器,它们都开始滴答作响,并将永远如此。 clearInterval 代码永远不会被执行。

标签: javascript jquery setinterval clearinterval


【解决方案1】:

您需要考虑到异步代码不会停止当前的执行代码。您传递给setInterval 的回调函数是异步调用的,即当前正在执行的代码已经完成,直到调用堆栈为空为止。

所以setInterval 不会以某种方式等待几秒钟过去。 for 循环将立即完成所有迭代,创建了同样多的 setInterval 计时器,所有这些计时器都开始计时之后,并将永远如此。 clearInterval 代码永远不会被执行。

您可以这样做,利用异步“循环”,即使用多次异步调用的函数。

function changesystem(lottery,maxroundtime,firstloop){
    //loop asynchronously through lottery numbers
    (function loop(keys) {
        if (!keys.length) return; // all done
        var key = keys.shift(); // extract next key
        var currentnum = lottery[key].LotteryNum;
        console.log('lottery number', currentnum);
        var currentclass = lottery[key].ClassID;
        //display values
        $('#CurrentNumber').text(currentnum);
        $('#CurrentClass').text(currentclass);
        //change progress bar asynchronously 
        //every second until reaches max round time
        (function progress(loopControl) {
            console.log('loopControl', loopControl);
            if (!loopControl) {
                loop(keys); // done: continue with next lottery number
            } else { // schedule next progress tick
                setTimeout(progress.bind(null, loopControl-1), 1000);
            }
        })(5); // start with loopControl 5
    })(Object.keys(lottery)); // pass all keys
}

【讨论】:

  • 谢谢你的工作。我没有意识到这就是我以前发生的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-11
  • 1970-01-01
相关资源
最近更新 更多