Debugging feature implemented with promises

I am trying to implement a debounce function that works with promise in javascript. Thus, each caller can use the result of the "debounced" function using Promise. Here is the best I've 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 base version of EventEmitter), but I cannot figure out how to do this. Any thoughts?

+8
source share
5 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 initial question on how to implement this function without dependence on EventEmitter (or something like that).

+18
source

I got here because I wanted to get the return value of the promise, but instead, debounce in underscore.js returned undefined . I ended up using the lodash version with leading = true. This works for my case, because I don’t care whether the execution will be leading or ending.

https://lodash.com/docs/4.17.4#debounce

 _.debounce(somethingThatReturnsAPromise, 300, { leading: true, trailing: false }) 
+3
source

Do not understand what you are trying to accomplish, as this is highly dependent on your needs. However, there is something in common. Without a solid understanding of what happens in the code below, you really may not want to use it, though.

 // Debounce state constructor function debounce(f) { this._f = f; return this.run.bind(this) } // Debounce execution function debounce.prototype.run = function() { console.log('before check'); if (this._promise) return this._promise; console.log('after check'); return this._promise = this._f(arguments).then(function(r) { console.log('clearing'); delete this._promise; // remove deletion to prevent new execution (or remove after timeout?) return r; }.bind(this)).catch(function(r) { console.log('clearing after rejection'); delete this._promise; // Remove deletion here for as needed as noted above return Promise.reject(r); // rethrow rejection }) } // Some function which returns a promise needing debouncing function test(str) { return new Promise(function(resolve, reject) { setTimeout(function() { console.log('test' + str); resolve(); }, 1000); }); } a = new debounce(test); // Create debounced version of function console.log("p1: ", p1 = a(1)); console.log("p2: ", p2 = a(2)); console.log("p1 = p2", p1 === p2); setTimeout(function() { console.log("p3: ", p3 = a(3)); console.log("p1 = p3 ", p1 === p3, " - p2 = p3 ", p2 === p3); }, 2100) 

View the console as you run the code above. I put a few posts to talk a bit about what is happening. The first function that returns the promise is passed as the argument to new debounce() . This creates a debounced version of the function.

When you run the debounced function, as the above code ( a(1), a(2), and a(3) ) shows, you will notice that during processing it returns the same promise, rather than starting a new one. Once the promise is completed, it will delete the old promises. In the above code, I expect a timeout manually using setTimeout before running (3).

You can also clear the promise in other ways, for example, add a reset or clear function to debounce.prototype to clear the promise at another time. You can also set a timeout. Tests in the console log should show that p1 and p2 receive the same promise (link comparison === "true) and that p3 is different.

+1
source

This may not be what you want, but it may give you some clue:

 /** * Call a function asynchronously, as soon as possible. Makes * use of HTML Promise to schedule the callback if available, * otherwise falling back to 'setTimeout' (mainly for IE<11). * @type {(callback: function) => void} */ export const defer = typeof Promise=='function' ? Promise.resolve().then.bind(Promise.resolve()) : setTimeout; 
0
source

This is my implementation, only the last call in the interval will be allowed. In Chris’s decision, all calls will be resolved with a delay between them, which is good, but sometimes we only need to resolve the last call. Correct me if I am wrong.

 function debounce(f, interval) { let timer = null; return (...args) => { clearTimeout(timer); return new Promise((resolve) => { timer = setTimeout( () => resolve(f(...args)), interval, ); }); }; } 
0
source

All Articles