debouncePromise
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 usesetTimeout()
to create a new timeout that delays invoking the function until at leastms
milliseconds has elapsed. - Use
Function.prototype.apply()
to apply thethis
context to the function and provide the necessary arguments. - Create a new
Promise
and add itsresolve
andreject
callbacks to thepending
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 of0
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 });
});
};