Как сделать 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.