B
B
Bla Bla2021-02-10 12:18:23
Node.js
Bla Bla, 2021-02-10 12:18:23

Why doesn't the variable in the closure change?

There is a newMinute() function in the middle of the startTimer() function, on the first call it works correctly, there is a minute and it is subtracted and seconds becomes 60, but in another call, minutes, seconds - do not change. - With an arrow function.

class Timer {
    startTimer(minutes = 0, seconds = 0) {

        newMinute();//work

        const timerID = setInterval(() => {
            seconds = Math.round(seconds);

            newMinute();//don't work

            this.spanMinutes.innerText = minutes;
            this.spanSeconds.innerHTML = seconds;
        },1000)

        function newMinute() {//Higher I write when I use arrow function
            if (!seconds) {
                if (!minutes)
                    this.endTimer(timerID);// don't work maybe due context
                minutes--;//if I use arrow function minutes don't change
                seconds = 60;//also don't change
            }
        }
    }

    endTimer(timerID, timerProgressBar) {
        this.screenSettings.style.display = 'block';
        this.screenTimer.style.display = 'none';
        clearInterval(timerID);
        clearInterval(timerProgressBar);
    }
}

const timeLapse = new Timer();

timeLapse.btnStart.onclick = () => timeLapse.startTimer(1, 20);

Answer the question

In order to leave comments, you need to log in

1 answer(s)
W
WbICHA, 2021-02-10
@SubUser

Everything works exactly as you wrote.
newMinuteif seconds are zero, subtracts the minute and makes seconds equal to 60 (which should be 59 because 60 seconds = 0 seconds). Since seconds don't decrease anywhere ( seconds--), you end up with an infinite loop.
Moreover, newMinuteit still won't work, because you declared it through functionand it loses context.
Here, either bind the interval callback / itself newMinute, or use the arrow:

const newMinute = (timerID) => {//Higher I write when I use arrow function
        if (seconds < 1) {
          if (minutes < 1) {
            this.endTimer(timerID);// don't work maybe due context
            return;
          }
          minutes--;//if I use arrow function minutes don't change
          seconds = 59;//also don't change
          return;
        }
        seconds--;
      };

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question