Существует множество сервисов, которые необходимо выполнять либо через определенное время, либо через определенный интервал. Для запуска некоторых функций через некоторое время мы используем setTimeout, который берет некоторый фрагмент кода, который выполняется через определенное время. Для запуска некоторых функций через определенные промежутки времени мы обычно используем setInterval, который берет некоторый фрагмент кода, который выполняется через определенное время. Но здесь существуют некоторые проблемы с использованием setInterval. Давайте исследуем их.

const func = () => {
  activity A;   //having time consuming synchronous computations
  activity B;   //having time consuming synchronous computations
}
setInterval(func, 1000);

Предположим, есть функция fun, которую нужно вызывать через каждые 1000 мс, поток таймера в браузере начинает обратный отсчет, и когда время истечет, функция обратного вызова (в нашем случае func) помещается в стек выполнения потока javascript. Чтобы лучше понять, мы разобьем наше исполнение по времени.

При T=0 сек (изначально): В нашем стеке есть функция func с присоединенным таймером на 1 сек.

При T=1 сек: функция, присутствующая в нашем стеке, выскочила и начала выполняться. При этом функция func снова запихивается в стек с таймером 1 сек.

Теперь возникают два случая,

Случай 1: когда тело функции выполняется в течение 1 секунды.

Этот случай является нормальным, и код будет вести себя так, как ожидалось.

Случай 2: когда тело функции выполняется более 1 секунды.

В этом случае механизм ожидает завершения функции func, затем проверяет планировщик и немедленно запускает его, если время истекло. В крайнем случае, если функция func всегда выполняется дольше 1000 мс, то вызовы будут происходить вообще без паузы.

Примечание. Реальная задержка между вызовами функции setInterval меньше, чем в коде!

Теперь, что будет решением для этого? Мы можем использовать вложенный setTimeout. Позвольте мне рассказать вам, как это сделать.

const func = () => {
  activity A;   //having time consuming synchronous computations 
  activity B;   //having time consuming synchronous computations
  setTimeout(func, 1000);
}
setTimeout(func, 1000);

Опять же, мы собираемся разбить наше исполнение во времени.

При T=0 сек (изначально): В нашем стеке есть функция func с присоединенным таймером на 1 сек.

В T = 1 сек: функция, присутствующая в нашем стеке, выскочила и начала выполняться, теперь после завершения действий A и B (предположим, что это занимает x секунд)

При T= (1+x) сек: теперь выполняется setTimeout, который снова помещает функцию func в стек с присоединенным таймером на 1 секунду.

Точно так же через ((1+x )+ (1)) сек снова начинается выполнение функции func, и это продолжается.

Если вы что-то заметили, вложенный setTimeout гарантирует фиксированную задержку (здесь 1 с) при выполнении функции.

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

delay = 1000;
const func = () => {
  activity A;   //having time consuming synchronous computations 
  activity B;   //having time consuming synchronous computations
  delay += 1000;
  setTimeout(func, delay);
}
setTimeout(func, 1000);

Из приведенного выше фрагмента кода выполнение функции происходит в ряду арифметической прогрессии, где общая разница составляет 1000 мс, а начальное значение равно 1000 мс.

Использование:

Пример: Например, если нам нужно написать сервис, который отправляет запрос на сервер каждые 8 ​​секунд, запрашивая данные, но если сервер перегружен, он должен увеличить интервал до 8, 16 или 24 секунд…

Пример: если функции, которые мы планируем, потребляют ресурсы ЦП, то мы можем измерить время, затрачиваемое на выполнение, и спланировать следующий вызов раньше или позже.

Если вы думаете об использовании setInterval в своем фрагменте кода, остановитесь на минуту и ​​подумайте, можем ли мы использовать вложенный setTimeout.Это все еще стоит.

Для получения дополнительной информации:

LinkedIn: https://www.linkedin.com/in/shivam-agrawal-a4a414181/

GitHub: https://github.com/shivam1192