Что такое setInterval? Для чего нужен и как он работает?

👨‍💻 Frontend Developer 🟠 Может встретиться 🎚️ Легкий
#JavaScript #Асинхронность #База JS

Быстрый ответ

setInterval — это метод в JavaScript, который позволяет выполнять функцию или фрагмент кода многократно с заданным интервалом в миллисекундах. Он не блокирует выполнение основного потока кода, а регистрирует таймер и продолжает выполнение. Это основной инструмент для создания повторяющихся асинхронных операций, таких как таймеры, анимации или периодические запросы на сервер, без замораживания пользовательского интерфейса. Для отмены таймера используется clearInterval.


Что такое setInterval

setInterval — это встроенная функция в браузерах и Node.js, которая позволяет планировать многократное выполнение функции через определённый промежуток времени. Она возвращает числовой идентификатор таймера, который можно использовать для его отмены.

Синтаксис

const intervalId = setInterval(callback, delay, ...args);
  • callback: Функция, которая будет выполняться.
  • delay: Интервал в миллисекундах (1000 мс = 1 секунда). Если не указан, по умолчанию равен 0.
  • ...args: Дополнительные аргументы, которые будут переданы в callback при каждом её вызове.

Как это работает: Цикл событий (Event Loop)

setInterval не гарантирует, что функция будет выполняться точно через указанный интервал. Он гарантирует, что она будет добавляться в очередь обратных вызовов не реже, чем через delay.

  1. Вызов setInterval передаёт таймер в Web APIs.
  2. Основной поток JavaScript продолжает выполняться, не блокируясь.
  3. Когда таймер истекает, callback помещается в очередь обратных вызовов (callback queue).
  4. Цикл событий (Event Loop) проверяет, пуст ли стек вызовов.
  5. Как только стек становится пустым, callback из очереди перемещается в стек и выполняется.
  6. После выполнения callback таймер сбрасывается и начинается новый отсчет.

Важно: если выполнение callback занимает больше времени, чем delay, новый вызов может быть поставлен в очередь сразу после завершения предыдущего, что приведет к выполнению без пауз.


Примеры использования

1. Простой таймер

let counter = 0;
 
const intervalId = setInterval(() => {
  counter++;
  console.log(`Прошло ${counter} сек.`);
 
  if (counter >= 5) {
    clearInterval(intervalId);
    console.log("Таймер остановлен.");
  }
}, 1000);

Вывод в консоль:

  1. “Прошло 1 сек.”
  2. “Прошло 2 сек.”
  3. “Прошло 3 сек.”
  4. “Прошло 4 сек.”
  5. “Прошло 5 сек.”
  6. “Таймер остановлен.”

2. Передача аргументов в callback

function greet(name, phrase) {
  console.log(`${phrase}, ${name}!`);
}
 
setInterval(greet, 2000, "Александр", "Добрый день");
// Каждые 2 секунды будет выводить: "Добрый день, Александр!"

3. Отмена таймера с помощью clearInterval

Если вы хотите отменить запланированное выполнение, используйте clearInterval, передав ему intervalId.

let counter = 0;
const intervalId = setInterval(() => {
  console.log("Это сообщение будет появляться каждые 2 секунды.");
  counter++;
  if (counter > 2) {
    clearInterval(intervalId);
    console.log(`Таймер с ID ${intervalId} был отменен.`);
  }
}, 2000);

Задачи для практики

Задача 1

// Что выведет этот код? Будет ли он работать вечно?
let i = 0;
setInterval(() => {
  i++;
  console.log(i);
}, 100);
 
setTimeout(() => {
  // Что произойдет, если мы попытаемся изменить i здесь?
  i = 1000;
}, 500);
Ответ **Ответ:** Код будет выводить числа, начиная с 1, с интервалом 100 мс. Через 500 мс (когда `i` будет равно примерно 5), `setTimeout` изменит `i` на 1000. Следующий вызов `setInterval` увеличит `i` до 1001 и выведет его. Код будет работать вечно, так как нет `clearInterval`.

Задача 2

// Напишите функцию, которая создает цифровые часы в консоли,
// обновляя время каждую секунду. Формат: HH:MM:SS.
 
function digitalClock() {
  // Ваш код
}
 
digitalClock();
Ответ
function digitalClock() {
  setInterval(() => {
    const now = new Date();
    const hours = String(now.getHours()).padStart(2, '0');
    const minutes = String(now.getMinutes()).padStart(2, '0');
    const seconds = String(now.getSeconds()).padStart(2, '0');
    console.log(`${hours}:${minutes}:${seconds}`);
  }, 1000);
}

Объяснение: Мы используем setInterval для ежесекундного выполнения функции. Внутри мы получаем текущее время, форматируем его с помощью padStart для добавления ведущих нулей и выводим в консоль.