How to debounce a function
Short answer
Debounce postpones the call. Every new call cancels the previous timer, so the function runs only after a pause:
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');Output:
searching for javaIn a search field
A typical use is a search request that is sent only when the user stops typing:
<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>Common mistake
Create the debounced function once. If you create it inside the event handler, each event gets its own timer and nothing is cancelled:
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');Output:
search a
search ab
search abcFunctions used in this recipe
- setTimeout — Runs a function once after a delay.
- clearTimeout — Cancels a scheduled setTimeout.