Throttle
Вызов срабатывает сразу, но не чаще раза в интервал — лишние события дропаются.
1function throttle(fn: () => void, intervalMs: number): () => void {2 let lastCall = -Infinity3 4 return () => {5 const now = Date.now()6 if (now - lastCall >= intervalMs) {7 lastCall = now8 fn()9 }10 }11}Проблема
События сыплются чаще, чем можно реагировать (scroll, mousemove, тики сенсора). Debounce дождётся тишины — но иногда нужен ответ именно сейчас, просто ограниченный по частоте: не чаще раза в N миллисекунд.
Что вы видите
Таймлайн: точки — события. Событие внутри интервала от последнего вызова гаснет с пометкой «дроп»: окно не сдвигается (ключевое отличие от debounce). Вызов случается в сам момент события.
Как это работает
Throttle хранит время последнего вызова. Пришла серия событий: если с прошлого вызова прошло ≥ interval — вызываем сразу и запоминаем время; иначе — молча выбрасываем. Окно не двигается: throttle гарантирует ритм «раз в интервал», а debounce — «после паузы».
Пошаговый разбор
- 01
Событие
Обёртка вызвана в момент t.
- 02
Проверка
t − lastCall ≥ interval?
- 03
Да — вызов
fn() срабатывает немедленно, lastCall = t.
- 04
Нет — дроп
Событие отбрасывается, окно не сдвигается.
Complexity и ограничения
Leading-edge вариант: без хвостового вызова. Интервал подбирается по задаче: scroll ~16-100 мс.
Edge cases
- Первое событие
lastCall = −∞ — вызов гарантированно срабатывает.
- Ровно интервал
t − lastCall = interval — вызов считается допустимым.
- Ровный ритм
События реже interval — throttle вообще ничего не режет.
Где встречается в реальности
scroll-обработчики
Пересчёт sticky-шапки/параллакса не чаще кадра-двух.
Игровой ввод
Автоогонь: нажатие удержано — выстрелы раз в N мс.
Метрики/аналитика
Отправка телеметрии не чаще раза в интервал при залпе событий.
Связанные алгоритмы
«5 событий — 3 вызова. А debounce сделал бы 2. В чём разница?»
Тот же сценарий StepSequence в вертикальной композиции — с safe zones и записью WebM ниже на странице.
Shorts 9:16
Вертикальная композиция строится той же последовательностью шагов, что и страница: safe zones отмечены пунктиром (там живёт UI платформ), биты сценария подсвечиваются по прогрессу. Кнопка записи сохраняет WebM — детерминированная StepSequence даёт воспроизводимый ролик без монтажа.