I am currently learning debounce in Javascript and I came across two ways of writing debounce functions that works the same. One is a lot simpler like regular function, the other one is the complicated one that everyone seems to use.
<input type="text" oninput="betterFunction()">
<script>
function getData() {
  console.log('Data Fetched')
}
function debounce(callback, delay) {
  let timer
  return function() {
    clearTimeout(timer)
    timer = setTimeout(() => {
      callback();
    }, delay)
  }
}
const betterFunction = debounce(getData, 1000)
</script>
<input type="text" oninput="debounce()">
<script>
let timer
function debounce() {
  clearTimeout(timer)
  timer = setTimeout(() => {
    console.log('Data Fetched');
  }, 1000)
}
</script>
What is the difference between these two ways of debouncing if they both gives the same result? PS: I am surprised that I have never seen anyone use the 'version 2', ofcourse something must me wrong. Could anybody explain the differences please?
Version 1 is better, because it:
timer (timeout ID) within the scope of—the lifetime of—the function callJosh W Comeau has an informative article covering debounce.
Here is his (modified) minimal version:
const debounce = (callback, wait) => {
  let timeoutId = null;
  return (...args) => {
    window.clearTimeout(timeoutId);
    timeoutId = window.setTimeout(() => {
      callback(...args);
    }, wait);
  };
}
Note: I replaced the callback.apply(null, args) with the more succinct callback(...args)
const handleMouseMove = debounce((mouseEvent) => {
  // Do stuff with the event!
}, 250);
document.addEventListener('mousemove', handleMouseMove);    // Add listener
document.removeEventListener('mousemove', handleMouseMove); // Remove listener
In the snippet below, points are drawn every time the user stops moving the mouse after 250ms. Each point is auto-removed after 2 seconds.
const debounce = (callback, wait) => {
  let timeoutId = null;
  return (...args) => {
    window.clearTimeout(timeoutId);
    timeoutId = window.setTimeout(() => {
      callback(...args);
    }, wait);
  };
}
const createPoint = (x, y, color) => {
  const point = Object.assign(document.createElement('div'), { className: 'point' });
  Object.assign(point.style, { top: `${y - 2}px`, left: `${x - 2}px`, background: color });
  document.body.append(point);
  return point;
};
// Log mouse coordinates when user stops moving mouse after 250ms
const handleMouseMove = debounce(({ clientX: x, clientY: y }) => {
  console.log(`Creating MOVE point at: (${x}, ${y})`);
  const point = createPoint(x, y, 'white');
  // Auto-remove after 1 second
  setTimeout(() => {
    console.log(`Removing MOVE point at: (${x}, ${y})`);
    point.remove();
  }, 2000);
}, 250);
// Log mouse coordinates when user stops clicking 250ms
const handleClick = debounce(({ clientX: x, clientY: y }) => {
  console.log(`Creating CLICK point at: (${x}, ${y})`);
  const point = createPoint(x, y, 'red');
  // Auto-remove after 1 second
  setTimeout(() => {
    console.log(`Removing CLICK point at: (${x}, ${y})`);
    point.remove();
  }, 2000);
}, 250);
document.addEventListener('mousemove', handleMouseMove);
document.addEventListener('click', handleClick);
.as-console-wrapper { max-height: 5em !important; }
html, body { width: 100%; height: 100%; margin: 0; padding: 0; }
body { background: #222; position: relative; }
.point { position: absolute; width: 4px; height: 4px; border-radius: 50%; background: #FFF; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With