ClearInterval () не останавливает интервал

Хорошо, прежде чем отмечать это как дубликат, прочтите, пожалуйста, полностью.

Итак, я новичок в JS. Пытаюсь сделать таймер. Предполагается, что каждый раз, когда вызывается функция timerReset(), интервал должен быть перезапущен. У меня есть это:

intervalID = setInterval(wallsPingTimer, wallsTime); //INTERVAL IS DEFINED ON STARTUP
wallsTime = 10000;
wallsToggle = true

function timerReset() {
    if (wallsToggle === true) {
        console.info('Timer has been reset');
        clearInterval(intervalID);
        intervalID = setInterval(wallsTimerPing, wallsTime);
    }
    if (wallsToggle === false) {
        console.info('Timer is disabled');
    }
}

function wallsPingTimer() {
//some code
}

Таймер запускается при запуске intervalID = setInterval(wallsTimerPing, wallsTime), но старый таймер никогда не останавливается. В итоге происходит то, что wallsTimerPing() запускается на нескольких таймерах снова и снова. clearInterval(intervalID) никогда не останавливает оригинал, и я сбит с толку.

Я просмотрел множество других подобных вопросов, и, похоже, я делаю это правильно (очевидно, нет). В чем дело?

setInterval() принимает ссылку на функцию в качестве первого аргумента. Что такое wallsTimerPing? Обновите свой вопрос, чтобы отобразить весь связанный с ним код.
Scott Marcus 11.09.2018 21:40

Показанный код выглядит правильно. Как вы используете timerReset и как заключаете, что интервал не сбрасывается?

charlietfl 11.09.2018 21:43

за clearInterval следует setInterval в вашем коде, поэтому функция wallTimerPing никогда не перестанет выполнять

Stakvino 11.09.2018 21:43

@ScottMarcus Обновлено, WallTimerPing - это функция. @charlietfl timerReset выполняется другими функциями. Это бот в discord.js, поэтому, когда используется определенная команда, она выполняется. @Stakvino таймер должен быть перезапущен, это сделано намеренно. Эта часть работает, старый интервал просто продолжается ...

rainy 11.09.2018 21:48

Вы определили wallTime ПОСЛЕ того, как вы его используете?

epascarello 11.09.2018 21:48

@epascarello WallTime определяется в начале скрипта, я поместил его вверху, чтобы показать это.

rainy 11.09.2018 21:49

По-прежнему не показано, где изменяется wallsToggle или как вы вызываете timerRest. Действительно нужен минимальный воспроизводимый пример, который воспроизводит проблему

charlietfl 11.09.2018 21:57

Откуда вы знаете, что это старый таймер, который все еще работает, а не новый, вы очищаете старый, а затем сразу же передаете те же значения новому. Опубликуйте свой полный код, если вам нужна помощь.

rmn 11.09.2018 21:58

Похоже, вам нужно показать реальный код.

epascarello 11.09.2018 22:03

Пожалуйста, посмотрите мой обновленный ответ, в котором подробно рассказывается о том, что именно ваш код делает в настоящее время, и показаны два шаблона для успешной работы вашего таймера.

Scott Marcus 12.09.2018 18:09
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
10
406
1

Ответы 1

Проблема в том, что вы проверяете wallsToggle на наличие true или false (и, возможно, останавливаете таймер), когда timerReset впервые запускается, и эта функция запускает ваш таймер, который затем вызывает wallsTimerPing, но timerReset больше не запускается, и поэтому clearInterval() останавливается. таймер работы никогда не срабатывает.

Вот пошаговая инструкция:

  1. wallsToggle установлен на true
  2. timerReset() называют
  3. wallsToggle протестирован на true
  4. wallsToggle - это true, поэтому вводится ветвь trueif.
  5. "Timer has been reset" зарегистрирован
  6. clearInterval() вызывается, но таймер еще не запущен, поэтому ничего не происходит
  7. Вызывается setInterval(), и по истечении интервала wallsTimerProg() помещается в очередь событий и запускается новый счетчик интервалов.
  8. Выполняется второй оператор if, но wallsToggle по-прежнему является true, поэтому его ветвь true не вводится.
  9. timerReset() завершен.
  10. wallsTimerProg() выполняет.
  11. Что-то может или не может произойти в wallsTimerProg(), что устанавливает wallsToggle в false
  12. wallsTimerProg() завершается
  13. Интервал достигнут, и шаг 7 повторяется снова.
  14. Когда стек вызовов бездействует, шаги 10-13 повторяются снова.
  15. Шаг 7, за которым следует 14, продолжаются бесконечно, потому что wallsTimerProg() не имеет кода, который очищает таймер.

Ваш шаблон был бы правильным, если бы таймер рекурсивно вызывал timerReset, потому что тесты if / then будут запускаться при каждом вызове функции, и clearInterval() потенциально может получить срабатывание.

let intervalID;
wallsTime = 2000;
wallsToggle = true


function timerReset() {
    console.info("wallsToggle is: " + wallsToggle);
    
    // The code that determines if the timer should continue should 
    // be in the function that will be called repeatedly.
    if (wallsToggle === true) {
        console.info('Timer has been reset');
        intervalID = setInterval(timerReset, wallsTime);
    } else  { // <-- If a Boolean isn't true, it must be false. No need to check
        // Clear the interval when you've determined that you need to stop
        clearInterval(intervalID);  
        console.info('Timer is disabled');
    }
    
  // The main code that this function does here
  // along with something that would change wallsToggle to false
  wallsToggle = false;
}

timerReset();

Но если вы хотите / нуждаетесь в том, чтобы вторая функция вызывалась таймером, вам необходимо переместить код, определяющий, должен ли таймер снова запускаться, в функцию, которую вызывает clearInterval(), а не в функцию, которая запускается один раз и запускает операцию. .

Вот пример того, как это должно работать:

let intervalID;
wallsTime = 2000;
wallsToggle = true

function wallsTimerPing(){
    console.info("wallsToggle is: " + wallsToggle);
    
    // The code that determines if the timer should continue should 
    // be in the function that will be called repeatedly.
    if (wallsToggle === true) {
        console.info('Timer has been reset');
    } else  { // <-- If a Boolean isn't true, it must be false. No need to check
        // Clear the interval when you've determined that you need to stop
        clearInterval(intervalID);  
        console.info('Timer is disabled');
    }
    
  // The main code that this function does here
  // along with something that would change wallsToggle to false
  wallsToggle = false;
}

function timerReset() {
   intervalID = setInterval(wallsTimerPing, wallsTime);
}

timerReset();

Другие вопросы по теме