-
-
Save getify/f55b2bcb4c90dc239918836fada0e98a to your computer and use it in GitHub Desktop.
Scheduler (debouncing + throttling) | https://codepen.io/getify/pen/LYPbmYG?editors=0012
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
| // 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) | |
| // .. |
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
| 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(); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
thank you for the detailed answer