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 leastmsmilliseconds has elapsed. - Use
Function.prototype.apply()to apply thethiscontext to the function and provide the necessary arguments. - Create a new
Promiseand add itsresolveandrejectcallbacks to thependingpromises stack. - When
setTimeoutis 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 of0ms.
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 });
});
};