setInterval 在第一次调用时被跳过,而 Clearinterval 在调用时不停止 Javascript

setInterval being skipped the first call and Clearinterval not stopping when called Javascript

我正在尝试创建一个计时器,它每秒都会调用另一个函数。所以我在 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

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

所以 setInterval 不会以某种方式等待秒数过去。 for 循环将立即完成所有迭代,创建了同样多的 setInterval 计时器,它们都开始计时 afterwards,并将继续这样做曾经。 clearInterval 代码永远不会执行。

这是你如何做到的,利用异步 "loops",即使用异步调用多次的函数。

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
}