ms
milliseconds have elapsed since the last time it was invoked.
All promises returned during this time will return the same data.clearTimeout()
and use setTimeout()
to create a new timeout that delays invoking the function until at least ms
milliseconds has elapsed.Function.prototype.apply()
to apply the this
context to the function and provide the necessary arguments.Promise
and add its resolve
and reject
callbacks to the pending
promises stack.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.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
Subscribe to get resources directly to your inbox. You won't receive any spam! ✌️