← Назад к вопросам

Что такое Debounce?

1.0 Junior🔥 201 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Debounce — управление частотой вызовов функций

Debounce — это техника программирования, которая предотвращает выполнение функции до тех пор, пока не пройдёт определённое время после последнего события. Проще говоря: если событие происходит многократно подряд, функция выполнится только один раз после того, как события прекратятся.

Когда используется

Debounce критически важен для оптимизации производительности приложения:

  • Поиск — при вводе в поле поиска не стоит отправлять запрос на каждый символ
  • Ресайз окна — пересчёт макета на каждый пиксель изменения размера окна неэффективен
  • Автосохранение — сохранять на сервер при каждом изменении текста в редакторе — расточительно
  • Валидация формы — проверка email адреса на сервере должна происходить не чаще чем раз в N мс
  • Отслеживание скролла — обработка скролла может вызывать множество событий в секунду

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

Когда пользователь начинает печатать в поле поиска:

  1. Первый символ → запускается таймер (например, 500мс)
  2. Второй символ → таймер сбрасывается (отсчёт начинается заново)
  3. Третий символ → опять сброс таймера
  4. Пауза в 500мс → таймер завершается, функция выполняется
  5. Затем весь цикл повторяется

Реализация Debounce

// Простая реализация debounce
function debounce<T extends (...args: any[]) => any>(
  func: T,
  delay: number
): (...args: Parameters<T>) => void {
  let timeoutId: NodeJS.Timeout | null = null;

  return function (...args: Parameters<T>) {
    // Отменяем предыдущий таймер
    if (timeoutId !== null) {
      clearTimeout(timeoutId);
    }

    // Устанавливаем новый таймер
    timeoutId = setTimeout(() => {
      func(...args);
      timeoutId = null;
    }, delay);
  };
}

// Использование
const handleSearch = debounce((query: string) => {
  console.log("Поиск по:", query);
  // API запрос
  fetchSearchResults(query);
}, 500);

// В компоненте
<input 
  onChange={(e) => handleSearch(e.target.value)}
  placeholder="Поиск..."
/>

Debounce с возвращаемым значением

function debounceAsync<T extends (...args: any[]) => Promise<any>>(
  func: T,
  delay: number
): (...args: Parameters<T>) => Promise<void> {
  let timeoutId: NodeJS.Timeout | null = null;

  return async function (...args: Parameters<T>) {
    if (timeoutId !== null) {
      clearTimeout(timeoutId);
    }

    return new Promise<void>((resolve) => {
      timeoutId = setTimeout(async () => {
        await func(...args);
        timeoutId = null;
        resolve();
      }, delay);
    });
  };
}

Debounce vs Throttle

Важно не путать с похожей техникой Throttle:

  • Debounce — выполнить функцию после завершения серии событий
  • Throttle — выполнить функцию не чаще чем раз в N миллисекунд (даже если события продолжаются)
// Throttle пример
function throttle<T extends (...args: any[]) => any>(
  func: T,
  limit: number
): (...args: Parameters<T>) => void {
  let inThrottle = false;

  return function (...args: Parameters<T>) {
    if (!inThrottle) {
      func(...args);
      inThrottle = true;
      setTimeout(() => (inThrottle = false), limit);
    }
  };
}
Что такое Debounce? | PrepBro