Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що таке debounce і throttle і як їх реалізувати?

Обидва обмежують, як часто спрацьовує функція, яку викликають дуже часто: введення тексту, scroll, resize, рух миші.

  • Debounce - виконати один раз, коли виклики припинилися на заданий час. Пошук під час набору: запит іде, коли користувач перестав друкувати на 300 мс.
  • Throttle - виконувати не частіше ніж раз на заданий проміжок, поки виклики тривають. Позиція скролу для прогрес-бару: раз на 100 мс, а не 60 разів на секунду.

Обидва - класичний приклад замикань: таймер і час останнього виклику живуть у зовнішній функції.

function debounce(fn, wait) {
  let timer;
  return function (...args) {
    clearTimeout(timer);
    timer = setTimeout(() => fn.apply(this, args), wait);
  };
}

function throttle(fn, wait) {
  let last = 0;
  return function (...args) {
    const now = Date.now();
    if (now - last >= wait) {
      last = now;
      fn.apply(this, args);
    }
  };
}

input.addEventListener('input', debounce((e) => search(e.target.value), 300));

Що питають на старших рівнях:

  • Leading / trailing: чи виконувати функцію на початку серії, наприкінці чи обидва рази. Throttle вище втрачає останній виклик серії - для прогрес-бару це помилка, бо фінальна позиція не потрапить.
  • Скасування: debounce у компоненті треба вміти скасувати при його знищенні, інакше колбек спрацює вже після того.
  • requestAnimationFrame - природний «throttle» для всього, що малює: не частіше за кадр.

Для debounce пошукових запитів додають ще AbortController: пізня відповідь на старий запит не має перезаписати свіжу.

Докладніше в документації: Debounce

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання