Skip to content

Instantly share code, notes, and snippets.

@getify
Last active August 26, 2019 16:15
Show Gist options
  • Select an option

  • Save getify/f55b2bcb4c90dc239918836fada0e98a to your computer and use it in GitHub Desktop.

Select an option

Save getify/f55b2bcb4c90dc239918836fada0e98a to your computer and use it in GitHub Desktop.
Scheduler (debouncing + throttling) | https://codepen.io/getify/pen/LYPbmYG?editors=0012
// NOTE: To see this demo: https://codepen.io/getify/pen/LYPbmYG?editors=0012
var counter = 1;
function printMessage() {
console.log(`message ${counter++}`);
}
var schedule = Scheduler(/* debounceMinimum = */50,/* throttleMaximum = */500);
// try to schedule a message to be printed (after approx 50ms of debounce)
schedule(printMessage);
setTimeout(function waitAWhile(){
// try to schedule next message to be printed (after approx 50ms of debounce)
schedule(printMessage);
// but now keep flooding the scheduling, so it keeps debouncing, up to the 500ms max throttling
var intv = setInterval(function(){ schedule(printMessage); },30);
// stop the madness, after about 10 seconds!
setTimeout(function(){ clearInterval(intv); },10*1000);
},3*1000);
// "message 1" (printed after about 50ms)
// (waiting about 3.5 seconds)
// "message 2"
// "message 3" (after another 500ms)
// "message 4" (after another 500ms)
// ..
function Scheduler(debounceMin,throttleMax) {
var entries = new WeakMap();
return schedule;
// ***********************
function schedule(fn) {
var entry;
if (entries.has(fn)) {
entry = entries.get(fn);
}
else {
entry = {
last: 0,
timer: null,
};
entries.set(fn,entry);
}
var now = Date.now();
if (!entry.timer) {
entry.last = now;
}
if (
// no timer running yet?
entry.timer == null ||
// room left to debounce while still under the throttle-max?
(now - entry.last) < throttleMax
) {
if (entry.timer) {
clearTimeout(entry.timer);
}
let time = Math.min(debounceMin,Math.max(0,(entry.last + throttleMax) - now));
entry.timer = setTimeout(run,time,fn,entry);
}
}
function run(fn,entry) {
entry.timer = null;
entry.last = Date.now();
fn();
}
}
@ValeraS
Copy link
Copy Markdown

ValeraS commented Aug 26, 2019

thank you for the detailed answer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment