DEV//UNIT
← АлгоритмыReal-world Development

Throttle

Вызов срабатывает сразу, но не чаще раза в интервал — лишние события дропаются.

время O(1) на событиепамять O(1)уровень: начальный
Что происходит сейчас0/0
Нажмите Play, чтобы запустить сценарий
TypeScript — активная строка подсвечена шагом
1function throttle(fn: () => void, intervalMs: number): () => void {
2 let lastCall = -Infinity
3
4 return () => {
5 const now = Date.now()
6 if (now - lastCall >= intervalMs) {
7 lastCall = now
8 fn()
9 }
10 }
11}

Проблема

События сыплются чаще, чем можно реагировать (scroll, mousemove, тики сенсора). Debounce дождётся тишины — но иногда нужен ответ именно сейчас, просто ограниченный по частоте: не чаще раза в N миллисекунд.

Что вы видите

Таймлайн: точки — события. Событие внутри интервала от последнего вызова гаснет с пометкой «дроп»: окно не сдвигается (ключевое отличие от debounce). Вызов случается в сам момент события.

Как это работает

Throttle хранит время последнего вызова. Пришла серия событий: если с прошлого вызова прошло ≥ interval — вызываем сразу и запоминаем время; иначе — молча выбрасываем. Окно не двигается: throttle гарантирует ритм «раз в интервал», а debounce — «после паузы».

Пошаговый разбор

  1. 01

    Событие

    Обёртка вызвана в момент t.

  2. 02

    Проверка

    t − lastCall ≥ interval?

  3. 03

    Да — вызов

    fn() срабатывает немедленно, lastCall = t.

  4. 04

    Нет — дроп

    Событие отбрасывается, окно не сдвигается.

Complexity и ограничения

time
O(1) на событие
space
O(1)

Leading-edge вариант: без хвостового вызова. Интервал подбирается по задаче: scroll ~16-100 мс.

Edge cases

  • Первое событие

    lastCall = −∞ — вызов гарантированно срабатывает.

  • Ровно интервал

    t − lastCall = interval — вызов считается допустимым.

  • Ровный ритм

    События реже interval — throttle вообще ничего не режет.

Где встречается в реальности

scroll-обработчики

Пересчёт sticky-шапки/параллакса не чаще кадра-двух.

Игровой ввод

Автоогонь: нажатие удержано — выстрелы раз в N мс.

Метрики/аналитика

Отправка телеметрии не чаще раза в интервал при залпе событий.

Связанные алгоритмы

Shorts

«5 событий — 3 вызова. А debounce сделал бы 2. В чём разница?»

Тот же сценарий StepSequence в вертикальной композиции — с safe zones и записью WebM ниже на странице.

Shorts 9:16

Вертикальная композиция строится той же последовательностью шагов, что и страница: safe zones отмечены пунктиром (там живёт UI платформ), биты сценария подсвечиваются по прогрессу. Кнопка записи сохраняет WebM — детерминированная StepSequence даёт воспроизводимый ролик без монтажа.

5 событий — 3 вызова. А debounce сделал бы 2. В чём разница?
Нажмите Play
Бит 1/6 · 0–2 с
Hook: поток событий
script-setup.ru/algorithms/throttle