Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Как сделать debounce функции

Короткий ответ

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

function debounce(fn, ms) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), ms);
  };
}
 
const search = debounce((text) => console.log('searching for', text), 200);
 
search('j');
search('ja');
search('jav');
search('java');

Результат:

searching for java

В поле поиска

Типичное применение — поисковый запрос, который отправляется, когда пользователь перестал печатать:

<input id="search" placeholder="Search">
<p id="result"></p>
<script>
  function debounce(fn, ms) {
    let timer;
    return (...args) => {
      clearTimeout(timer);
      timer = setTimeout(() => fn(...args), ms);
    };
  }
 
  const input = document.getElementById('search');
  input.addEventListener('input', debounce(() => {
    document.getElementById('result').textContent = 'Searching for: ' + input.value;
  }, 300));
</script>

Частая ошибка

Создавайте функцию с debounce один раз. Если создавать её внутри обработчика события, у каждого события будет свой таймер и ничего не отменится:

function debounce(fn, ms) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), ms);
  };
}
 
const onInput = (text) => debounce(() => console.log('search', text), 100)();
 
onInput('a');
onInput('ab');
onInput('abc');

Результат:

search a
search ab
search abc

Функции из этого ответа

  • setTimeout — Выполняет функцию один раз через заданное время.
  • clearTimeout — Отменяет запланированный setTimeout.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.