Angelos Orfanakos

DIY throttle function in JavaScript

I recently wanted to throttle a function in a Sinatra project without pulling npm, lodash and friends. So I came up with the following basic implementation:

function throttle(callback, waitMs = 0) {
  let throttled = false;

  return function () {
    if (throttled) return;

    throttled = true;

    setTimeout(
      function () {
        callback();
        throttled = false;
      },
      waitMs
    );
  };
}

Here’s a contrived example on how you could use it e.g. to validate a username without sending an XHR for each typed character:

document.addEventListener('DOMContentLoaded', function () {
  const usernameInput = document.getElementById('username');

  function handleUsernameInput() {
    const data = { username: usernameInput.value };
    const fetchOptions = {
      method: 'POST',
      body: JSON.stringify(data)
    };
    fetch('/validate-username', fetchOptions)
      .then(response => response.json())
      .then(data => {
        if (data.isValid) return;
        alert('Username is invalid!');
      })
      .catch(() => alert('Something went wrong!'));
  };

  const throttledHandleUsernameInput = throttle(handleUsernameInput, 200);
  greekText.addEventListener('input', throttledHandleUsernameInput);
});

200 ms after the first character is typed, the callback (handleUsernameInput) executes, collects the text and sends it to the backend. During these 200 ms, any other throttledHandleUsernameInput function calls are ignored thanks to the early return check for throttled in the throttle function. Once the callback has finished executing, throttled gets reset and the process repeats.