Created
December 5, 2010 00:40
-
-
Save micho/728639 to your computer and use it in GitHub Desktop.
Throttle and debounce examples
This file contains 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
// Run the function as soon as it's called, but prevent further calls during `delay` ms | |
// Example: function.throttle(200) will only run function() once every 200 ms. | |
// Useful, for example, to avoid constant processing while typing in a live search box. | |
Function.prototype.throttle = function(delay) { | |
var fn = this | |
return function() { | |
var now = (new Date).getTime() | |
if (!fn.lastExecuted || fn.lastExecuted + delay < now) { | |
fn.lastExecuted = now | |
fn.apply(fn, arguments) | |
} | |
} | |
} | |
// Instead of calling the function immediately, wait at least `delay` ms before calling it. | |
// Example: function.debounce(200) will only call the function after a 200ms pause. | |
// Useful, for example, to check an available username (wait to pause typing and check). | |
Function.prototype.debounce = function(delay) { | |
var fn = this | |
return function() { | |
fn.args = arguments | |
fn.timeout_id && clearTimeout(fn.timeout_id) | |
fn.timeout_id = setTimeout(function() { return fn.apply(fn, fn.args) }, delay) | |
} | |
} | |
setTimeout( function() { | |
times_called_yell = 0 | |
yell = function() { times_called_yell++ }.throttle(200) | |
setTimeout(yell, 0) // will fire | |
setTimeout(yell, 100) | |
setTimeout(yell, 250) // will fire | |
setTimeout(yell, 300) | |
setTimeout(yell, 350) | |
setTimeout(yell, 500) // will fire | |
setTimeout(function() { console.log(times_called_yell == 3 ? "[OK] Throttle is executed correctly" : "[FAILED] Throttle found args "+times_called_yell) }, 1000) | |
times_called_sing = 0 | |
sing = function() { times_called_sing++ }.debounce(100) | |
setTimeout(sing, 50) | |
setTimeout(sing, 120) | |
setTimeout(sing, 200) // will fire | |
setTimeout(sing, 400) | |
setTimeout(sing, 450) // will fire | |
setTimeout(function() { console.log(times_called_sing == 2 ? "[OK] Debounce is executed correctly" : "[FAILED] Debounce found args: "+times_called_sing) }, 1000) | |
f = function(a,b,c) { | |
console.log((a+b+c) == 66 ? "[OK] Throttle accepts args" : "[FAILED] Throttle failed with args: "+a+" "+b+" "+c) | |
}.throttle(100) | |
f(11,22,33) | |
g = function(a,b,c) { | |
console.log((a+b+c) == 66 ? "[OK] Debounce accepts args" : "[FAILED] Debounce failed with args: "+a+" "+b+" "+c) | |
}.debounce(100) | |
g(11,22,33) | |
context_object = new Object | |
context_object.some = "property" | |
context_throttle_test = function() { | |
console.log( this.some == "property" ? "[OK] Throttle sets `this` context" : "[FAILED] Throttle context: "+this) | |
}.bind(context_object).throttle(100) | |
context_throttle_test() | |
context_debounce_test = function() { | |
console.log( this.some == "property" ? "[OK] Debounce sets `this` context" : "[FAILED] Debounce context: "+this) | |
}.bind(context_object).debounce(100) | |
context_debounce_test() | |
}, 1000) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
came here off google, just wanted a quick
throttle
implementation.your
Function.prototype.throttle
won't fire if it's only called once since it last got fired, you need to use a timer.Rewrote it, it has a slight different approach and delays all calls with
delay
ms. Could be combined with yourlastExecuted
-logic to also be called immediately on first call.