2024-07-12 12:58:34 +02:00
|
|
|
export const debounce = ( callback, delayMs ) => {
|
2024-10-24 12:48:33 +02:00
|
|
|
const state = {
|
|
|
|
timeoutId: null,
|
|
|
|
args: null,
|
2024-07-12 12:58:34 +02:00
|
|
|
};
|
2024-10-24 12:48:33 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Cancels any pending debounced execution.
|
|
|
|
*/
|
|
|
|
const cancel = () => {
|
2024-10-24 16:57:36 +02:00
|
|
|
if ( state.timeoutId ) {
|
|
|
|
window.clearTimeout( state.timeoutId );
|
2024-10-24 12:48:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
state.timeoutId = null;
|
|
|
|
state.args = null;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Immediately executes the debounced function if there's a pending execution.
|
|
|
|
* @return {void}
|
|
|
|
*/
|
|
|
|
const flush = () => {
|
|
|
|
// If there's nothing pending, return early.
|
2024-10-24 16:57:36 +02:00
|
|
|
if ( ! state.timeoutId ) {
|
2024-10-24 12:48:33 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-10-24 16:57:36 +02:00
|
|
|
callback.apply( null, state.args || [] );
|
|
|
|
cancel();
|
2024-10-24 12:48:33 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
const debouncedFunc = ( ...args ) => {
|
|
|
|
cancel();
|
|
|
|
state.args = args;
|
|
|
|
state.timeoutId = window.setTimeout( flush, delayMs );
|
|
|
|
};
|
|
|
|
|
|
|
|
// Attach utility methods
|
|
|
|
debouncedFunc.cancel = cancel;
|
|
|
|
debouncedFunc.flush = flush;
|
|
|
|
|
|
|
|
return debouncedFunc;
|
2023-12-13 21:42:23 +02:00
|
|
|
};
|