Skip to content

Instantly share code, notes, and snippets.

@c-kick
Created March 14, 2023 13:43
Embed
What would you like to do?
Rate-limiter/debouncer module for JavaScript. See https://code.hnldesign.nl/demo/hnl.debounce.html
/**
*
* debounceThis ES6 module v1.2 (03-2023)
* Debounces/rate-limits the provided function (callback)
*
* Example usage:
*
* import {debounceThis} from "debouncer.mjs";
*
* window.addEventListener('scroll', debounceThis((e)=> {
* //function that will be debounced/rate-limited
* updateScrollPos('after-scroll');
* }, {
* //optional parameters, see _defaults below
* execStart: false,
* execWhile: false,
* execDone: true
* }))
*
* See demo at https://code.hnldesign.nl/demo/hnl.debounce.html
*/
const _defaults = {
threshold: 150, //time to wait
execStart: false, //execute callback once immediately?
execWhile: false, //execute callback at each threshold interval while debouncing function is being called?
execDone: true, //execute callback once debouncing function stops being called and threshold passed?
}
export function debounceThis(cb, opts) {
//get/set options
opts = Object.assign({
timer: 0,
whileTimer: 0,
busy: false,
}, _defaults, opts);
return function (...args) {
clearTimeout(opts.timer);
if (!opts.busy && opts.execStart) {
cb.apply(this, args);
opts.busy = true;
}
if (opts.execWhile && !opts.whileTimer) {
opts.whileTimer = setTimeout(() => {
cb.apply(this, args);
opts.whileTimer = false;
}, opts.threshold);
}
opts.timer = setTimeout(() => {
opts.busy = false;
if (opts.execDone) cb.apply(this, args);
clearInterval(opts.whileTimer);
}, opts.threshold);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment