SetInterval: примеры (JAVASCRIPT)

Функция setInterval для периодического выполнения кода
Раздел: Timer, Запуск
setInterval(callback (function), delay (number), ...args (any)): number

Функция setInterval

Метод setInterval() является частью Web API и глобального объекта в среде выполнения JavaScript, такой как браузер или Node.js. Он применяется, когда необходимо выполнять заданный код многократно, с фиксированной временной задержкой между повторениями. Это типично для создания циклов обновления, анимаций, периодических опросов сервера или автосохранения.

Синтаксис:
let intervalID = setInterval(func [, delay, arg1, arg2, ...]);
let intervalID = setInterval(code [, delay]);

Аргументы:

  • func: Функция, которая будет выполняться. Обязательный аргумент, если не используется строка с кодом.
  • delay: Временная задержка между вызовами функции в миллисекундах (1000 мс = 1 секунда). По умолчанию равно 0. Фактическая задержка может быть больше указанной из-за однопоточности и загруженности Event Loop.
  • arg1, arg2, ...: Дополнительные аргументы, которые передаются в вызываемую функцию func при каждом её выполнении. Поддерживаются не во всех средах (например, в старых IE).
  • code: Альтернативный вариант — строка, содержащая код для выполнения (не рекомендуется из-за проблем с безопасностью и производительностью, аналогично eval()).

Возвращаемое значение:
Метод возвращает числовой intervalID — уникальный идентификатор интервала. Этот идентификатор не равен нулю и используется для остановки выполнения интервала с помощью функции clearInterval(intervalID).

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

Пример 1: Базовое использование

let counter = 0;
let intervalId = setInterval(() => {
  console.log(`Прошло ${++counter} сек.`);
}, 1000);
// Через 5 секунд остановить
setTimeout(() => { clearInterval(intervalId); }, 5000);
Прошло 1 сек.
Прошло 2 сек.
Прошло 3 сек.
Прошло 4 сек.
Прошло 5 сек.

Пример 2: Передача аргументов в функцию

function showMessage(message, name) {
  console.log(`${message}, ${name}!`);
}
// Аргументы 'Привет' и 'Анна' передаются в showMessage
setInterval(showMessage, 1500, 'Привет', 'Анна');
Привет, Анна!
Привет, Анна!
...

Пример 3: Использование строки с кодом (не рекомендуется)

let x = 0;
setInterval("console.log('x = ' + x++)", 2000);
x = 0
x = 1
...

Похожие функции в JavaScript

setTimeout(func, delay, ...args)
Выполняет функцию или код один раз после указанной задержки. Возвращает timeoutID. Для создания цикла её можно рекурсивно вызывать внутри самой функции, что позволяет более гибко контролировать следующий вызов в зависимости от условий. Предпочтительнее для нерегулярных или зависимых от предыдущего выполнения задач.

requestAnimationFrame(callback)
Специализированный метод для создания плавной анимации. Он запрашивает выполнение функции перед следующей перерисовкой браузера (обычно 60 раз в секунду). Задержка автоматически синхронизирована с частотой обновления экрана, что делает анимации более эффективными. Используется вместо setInterval для визуальных анимаций.

Типичные ошибки

1. Накопление вызовов при долгом выполнении функции. Если код внутри setInterval выполняется дольше, чем установленная задержка, вызовы начинают накапливаться и выполняться без пауз.

setInterval(() => {
    let start = Date.now();
    while (Date.now() - start < 3000) {} // Долгая операция 3 сек
    console.log('Готово');
}, 1000); // Задержка всего 1 сек
// После первых 3 секунд вывод может быть лавинообразным

2. Отсутствие очистки интервала. Неиспользование clearInterval приводит к утечке памяти и продолжению работы интервала, даже если он больше не нужен.

function startProcess() {
    setInterval(() => console.log('Работаю'), 500);
}
startProcess();
// Интервал продолжает работать вечно

3. Потеря контекста this. При передаче метода объекта возникает проблема с контекстом.

let user = {
    name: 'Иван',
    sayHi() { console.log(this.name); }
};
setInterval(user.sayHi, 1000); // Ошибка: this = undefined/global

Решение: использовать обёртку или привязку контекста.

setInterval(() => user.sayHi(), 1000);
// или
setInterval(user.sayHi.bind(user), 1000);

Изменения в последних версиях

Спецификация функции setInterval остаётся стабильной. Основные изменения касаются среды выполнения, в частности, повышения точности таймеров и интеграции с микротасками Event Loop. В веб-браузерах неактивные вкладки могут замедлять или приостанавливать выполнение интервалов (частота снижается до 1 раза в секунду) для оптимизации производительности и энергопотребления. В Node.js интервалы работают независимо от цикла событий, но их точность также может страдать при высокой нагрузке.

Расширенные примеры

1. Динамическое изменение интервала. Интервал можно остановить и создать заново с другой задержкой.

Пример javascript
let delay = 1000;
let intervalId;
function startDynamicInterval() {
    intervalId = setInterval(() => {
        console.log(`Задержка: ${delay}мс`);
        clearInterval(intervalId);
        delay += 500; // Увеличиваем задержку
        if (delay <= 3000) startDynamicInterval();
    }, delay);
}
startDynamicInterval();
Задержка: 1000мс
Задержка: 1500мс
Задержка: 2000мс
Задержка: 2500мс
Задержка: 3000мс

2. Использование с Promise и асинхронными функциями. Важно помнить, что setInterval не ждёт разрешения промиса.

Пример javascript
async function fetchData() {
    // Имитация асинхронного запроса
    let data = await new Promise(res => setTimeout(() => res('Данные'), 300));
    console.log(data);
}
// Каждую секунду запускается новый асинхронный запрос, независимо от завершения предыдущего
setInterval(fetchData, 1000);

3. Точный счётчик с компенсацией дрейфа. Корректировка времени для компенсации задержек Event Loop.

Пример javascript
let expected = Date.now() + 1000;
let count = 0;
function accurateTimer() {
    count++;
    let drift = Date.now() - expected; // Вычисляем дрейф
    console.log(`Пройден шаг ${count}. Дрейф: ${drift}мс`);
    expected += 1000;
    // Компенсируем дрейф, вычитая его из следующей задержки
    setTimeout(accurateTimer, 1000 - drift);
}
setTimeout(accurateTimer, 1000);

4. Ограничение выполнения по времени. Интервал, который автоматически останавливается через заданный период.

Пример javascript
let startTime = Date.now();
let runTime = 10000; // 10 секунд
let interval = setInterval(() => {
    console.log('Работаю...');
    if (Date.now() - startTime > runTime) {
        clearInterval(interval);
        console.log('Время вышло');
    }
}, 1000);

5. Создание простой анимации движения. Хотя для анимаций лучше использовать requestAnimationFrame.

Пример javascript
<div id='box' style='width:50px;height:50px;background:blue;position:relative;'></div>
<script>
let pos = 0;
let box = document.getElementById('box');
let animId = setInterval(() => {
    pos += 5;
    box.style.left = pos + 'px';
    if (pos > 300) clearInterval(animId);
}, 50);
</script>

Альтернативы в других языках

PHP
В PHP нет точного аналога для выполнения кода в фоне на стороне сервера. Для периодических задач используют планировщик задач ОС (cron) или бесконечные циклы с sleep().

// Эмуляция с sleep в CLI
while (true) {
    echo 'Выполнено' . PHP_EOL;
    sleep(1); // Пауза 1 секунда
}

Python
Для периодического выполнения используют модуль threading.Timer или планировщик sched. В асинхронном коде — asyncio.create_task с asyncio.sleep.

import threading
def task():
    print('Повторяющаяся задача')
    threading.Timer(1.0, task).start() # Рекурсивный вызов
task()

C
Используют системные вызовы, такие как sleep() в цикле, или функции библиотеки для работы с временем.

#include <stdio.h>
#include <unistd.h>
int main() {
    while(1) {
        printf('Tick\n');
        sleep(1);
    }
    return 0;
}

MySQL
Периодические задачи настраиваются через системные события (CREATE EVENT), которые выполняются по расписанию на стороне сервера базы данных.

CREATE EVENT my_event
ON SCHEDULE EVERY 1 MINUTE
DO
  UPDATE table SET status = 'updated';

JS setInterval function comments

En
SetInterval Repeatedly executes a function with a fixed delay