Debounce promise

OSCC · JavaScript, Function, Promise · Oct 19, 2020

Creates a debounced function that returns a promise, but delays invoking the provided function until at least ms milliseconds have elapsed since the last time it was invoked. All promises returned during this time will return the same data.

  • Each time the debounced function is invoked, clear the current pending timeout with clearTimeout() and use setTimeout() to create a new timeout that delays invoking the function until at least ms milliseconds has elapsed.
  • Use Function.prototype.apply() to apply the this context to the function and provide the necessary arguments.
  • Create a new Promise and add its resolve and reject callbacks to the pending promises stack.
  • When setTimeout() is called, copy the current stack (as it can change between the provided function call and its resolution), clear it and call the provided function.
  • When the provided function resolves/rejects, resolve/reject all promises in the stack (copied when the function was called) with the returned data.
  • Omit the second argument, ms, to set the timeout at a default of 0 ms.
const debouncePromise = (fn, ms = 0) => {
  let timeoutId;
  const pending = [];
  return (...args) =>
    new Promise((res, rej) => {
      clearTimeout(timeoutId);
      timeoutId = setTimeout(() => {
        const currentPending = [...pending];
        pending.length = 0;
        Promise.resolve(fn.apply(this, args)).then(
          data => {
            currentPending.forEach(({ resolve }) => resolve(data));
          },
          error => {
            currentPending.forEach(({ reject }) => reject(error));
          }
        );
      }, ms);
      pending.push({ resolve: res, reject: rej });
    });
};
const fn = arg => new Promise(resolve => {
  setTimeout(resolve, 1000, ['resolved', arg]);
});
const debounced = debouncePromise(fn, 200);
debounced('foo').then(console.log);
debounced('bar').then(console.log);
// Will log ['resolved', 'bar'] both times

Recommended snippets & collections

  • JavaScript Promises

    Snippet collection

    JavaScript promises provide a modern and elegant way to to handle asynchronous operations. This snippet collection covers the basics of promises and how to use them in your code.

  • Creates a promise that resolves after a given amount of time to the provided value.

  • Pipe async functions

    JavaScript, Function

    Performs left-to-right function composition for asynchronous functions.

  • Run promises in series

    JavaScript, Function

    Runs an array of promises in series.