Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 511
Chris Avatar asked Feb 05 '16 15:02

Chris


People also ask

What is 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.

What is debounce and how could you implement debounce?

The debounce() function forces a function to wait a certain amount of time before running again. The function is built to limit the number of times a function is called. The Send Request() function is debounced. Requests are sent only after fixed time intervals regardless of how many times the user presses the button.


1 Answers

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).

like image 81
Chris Avatar answered Sep 30 '22 13:09

Chris