javascriptpromise

Debounce function implemented with promises


I'm trying to implement a debounce function that works with a promise in javascript. That way, each caller can consume the result of the "debounced" function using a Promise. Here is the best I have been able to come up with so far:

function debounce(inner, ms = 0) {
  let timer = null;
  let promise = null;
  const events = new EventEmitter();  // do I really need this?

  return function (...args) {
    if (timer == null) {
      promise = new Promise(resolve => {
        events.once('done', resolve);
      });
    } else {
      clearTimeout(timer);
    }

    timer = setTimeout(() => {
      events.emit('done', inner(...args));
      timer = null;
    }, ms);

    return promise;
  };
}

Ideally, I would like to implement this utility function without introducing a dependency on EventEmitter (or implementing my own basic version of EventEmitter), but I can't think of a way to do it. Any thoughts?


Solution

  • I found a better way to implement this with promises:

    function debounce(inner, ms = 0) {
      let timer = null;
      let resolves = [];
    
      return function (...args) {    
        // Run the function after a certain amount of time
        clearTimeout(timer);
        timer = setTimeout(() => {
          // Get the result of the inner function, then apply it to the resolve function of
          // each promise that has been created since the last time the inner function was run
          let result = inner(...args);
          resolves.forEach(r => r(result));
          resolves = [];
        }, ms);
    
        return new Promise(r => resolves.push(r));
      };
    }
    

    I still welcome suggestions, but the new implementation answers my original question about how to implement this function without a dependency on EventEmitter (or something like it).