setInterval пропускается при первом вызове, а Clearinterval не останавливается при вызове Javascript

Я пытаюсь создать таймер, который каждую секунду вызывает другую функцию. Поэтому я использую setInterval в цикле for.

setInterval пропускается во время первого цикла цикла for. Не уверен, почему.

Кроме того, у меня есть функция очистки интервала, когда он опускается ниже нуля. Когда у меня печатается сообщение в условиях остановки, оно выводится, но 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);
    }
  }

Наглядный пример


person Brit    schedule 11.03.2017    source источник
comment
ваш var timerloop затирается каждой итерацией вашего цикла for   -  person Jaromanda X    schedule 12.03.2017
comment
Углубление тоже затерто...   -  person trincot    schedule 12.03.2017
comment
Я думаю, вы можете предположить, что setInterval каким-то образом ждет, пока пройдут секунды, но это не так, цикл for сразу пройдет все итерации, создав столько же setInterval таймеров, которые все начнут тикать и будут продолжать это делать навсегда. Код clearInterval никогда не будет выполнен.   -  person trincot    schedule 12.03.2017


Ответы (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
}
person trincot    schedule 12.03.2017
comment
Спасибо, что сработало. Я не понимал, что происходит так, как я это делал раньше. - person Brit; 12.03.2017