Created
August 28, 2026 19:51
-
-
Save westc/a495c685c45649609c22ab422b7539a0 to your computer and use it in GitHub Desktop.
Creates a debounced function with an immediate side-effect callback and a maximum wait time (throttle) ceiling.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Creates a debounced function with an immediate side-effect callback | |
| * and a maximum wait time (throttle) ceiling. | |
| * | |
| * @param {Object} options - Configuration options for the debounce. | |
| * @param {number} options.waitMS - The delay in milliseconds to wait after the | |
| * last call before execution. | |
| * @param {Function} options.afterWait - The primary callback executed after the | |
| * debounce or maxWait period. | |
| * @param {Function} [options.immediate] - Optional function invoked immediately | |
| * on every call (errors are caught). | |
| * @param {number} [options.maxWaitMS] - The maximum delay in milliseconds | |
| * allowed before execution is forced. | |
| * @returns {Function} The new debounced wrapper function. | |
| */ | |
| function debounce({ waitMS, afterWait, immediate, maxWaitMS }) { | |
| // Validate required parameters | |
| if ((afterWait ?? null) === null) throw new Error('"afterWait" not provided.'); | |
| if ((waitMS ?? null) === null) throw new Error('"waitMS" not provided.'); | |
| let timeoutID, maxTimeoutID, maxTimeoutArgs; | |
| return function(...args) { | |
| // 1. Execute immediate callback on every invocation, suppressing any errors | |
| try { | |
| immediate?.apply(this, args); | |
| } catch { } | |
| // 2. Handle the maximum wait ceiling if configured | |
| if (maxWaitMS) { | |
| if (!maxTimeoutArgs) { | |
| maxTimeoutID = setTimeout( | |
| () => { | |
| clearTimeout(timeoutID); | |
| [args, maxTimeoutArgs] = [maxTimeoutArgs, null]; | |
| afterWait.apply(this, args); | |
| }, | |
| maxWaitMS | |
| ); | |
| } | |
| // Capture the latest arguments during the active maxWait window | |
| maxTimeoutArgs = args; | |
| } | |
| // 3. Reset and start the standard sliding debounce delay timer | |
| timeoutID = setTimeout( | |
| () => { | |
| clearTimeout(maxTimeoutID); | |
| maxTimeoutArgs = null; | |
| afterWait.apply(this, args); | |
| }, | |
| waitMS | |
| ); | |
| }; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment