Encodera

Thanks for reading!

Donate to the site — we work hard for you.

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 java

In 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 abc

Functions used in this recipe

Thanks for reading!

Donate to the site — we work hard for you.