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

Debounce

Функция вызовется только после паузы: серия событий схлопывается в один вызов в конце.

время O(1) на событиепамять O(1)уровень: начальный
Что происходит сейчас0/0
Нажмите Play, чтобы запустить сценарий
TypeScript — активная строка подсвечена шагом
1function debounce(fn: () => void, delayMs: number): () => void {
2 let timer: ReturnType<typeof setTimeout> | undefined
3
4 return () => {
5 if (timer !== undefined) clearTimeout(timer)
6
7 timer = setTimeout(() => {
8 timer = undefined
9 fn()
10 }, delayMs)
11 }
12}

Проблема

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

Что вы видите

Таймлайн с точками-событиями и «окном тишины». Каждое новое событие перезапускает таймер — окно сдвигается. Когда окно догорает без новых событий — срабатывает вызов. Пять событий, один вызов.

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

Debounce возвращает обёртку, которая при каждом вызове сбрасывает предыдущий таймер и ставит новый на delay мс. Реальный вызов происходит только если за delay мс не случилось ничего нового. Это «ожидание тишины»: полезно для поиска по мере ввода, автосохранения, ресайза.

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

  1. 01

    Событие

    Обёртка вызвана: clearTimeout предыдущего таймера.

  2. 02

    Новый таймер

    setTimeout(fn, delay) — окно тишины отсчитывается заново.

  3. 03

    Серия

    Каждое следующее событие до истечения delay снова перезапускает таймер.

  4. 04

    Тишина

    delay прошёл без событий — fn() наконец вызывается один раз.

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

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

Задержка подбирается по сценарию: поиск — 300 мс, автосейв — 1000 мс. Таймер надо чистить при unmount.

Edge cases

  • Бесконечный поток событий

    Если события приходят чаще delay, fn не вызовется никогда — для такого нужен throttle.

  • Одно событие

    Вызов ровно один, через delay.

  • Unmount

    Незачищенный таймер вызовет fn после размонтирования компонента — утечка.

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

Поиск с подсказками

Запрос уходит после того, как пользователь перестал печатать.

Автосохранение

Сохраняем черновик через секунду после последнего изменения.

Resize-вычисления

Дорогой пересчёт раскладки — один раз, когда окно перестало менять размер.

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

Shorts

«5 событий — 1 запрос. Как не заспамить сервер»

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

Shorts 9:16

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

5 событий — 1 запрос. Как не заспамить сервер
Нажмите Play
Бит 1/6 · 0–2 с
Hook: поиск-подсказки дёргаются на каждую букву
script-setup.ru/algorithms/debounce