Throttling function calls
If you've written any kind of validation on user input, like onkeypress then you'll know that sometimes you want to throttle the amount of times your function runs. A good example of this is Ajax based username validation - you don't want to hit the server on every key press, because most users will be able to write their name in around 1/10th of a second, so you should throttle the Ajax request until the input is dormant for 100ms.
So with a bit of magic JavaScript making use of the ever useful closure JavaScript offers, we can create a simple method to handle this for us:
function throttle(fn, delay) {
var timer = null;
return function () {
var context = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
};
}
So if you were doing something with jQuery, like a key press validation, you would do this instead:
$('input.username').keypress(throttle(function (event) {
// do the Ajax request
}, 250));
The keyword this is the input as you would expect, and all the correct arguments are passed to the event handle, i.e. it works the exact same way as you'd expect, except it only fires once the keypress event is idle for 250ms (in this particular case).
You should follow me on Twitter here I'll tweet about JavaScript, HTML 5 and other such gems (amongst usual tweet-splurges)
Introducing HTML5
What an elegant and useful little function! I think the name "throttle" might be a tad misleading, but I'll be damned if I can come up with a better name!
Ben Alman's fantastic description of throttling vs. debouncing might be helpful here:
http://benalman.com/projects/jquery-throttle-debounce-plugin/
Either way, thanks for sharing!
Heh, I wrote about this yesterday: http://fitzgeraldnick.com/weblog/32/
So did Angus Croll: http://javascriptweblog.wordpress.com/2010/07/19/a-javascript-function-guard/
Its a cool technique to say the least.
Good things come in threes
Why do you use "var args = arguments" instead of "arguments" ?
Is it only for a better reading experience? For performance (so why?)?
Thanks
@pop - because the
argumentsare required inside of the setTimeout firing. If I useargumentsin the setTimeout, they'd be blank since I hadn't passed any in.The first time I read about this technique (referred to most often as "debouncing") was in unscriptable's Debouncing Javascript Methods article.
Check out my jQuery throttle / debounce plugin (that David linked) for an in-depth explanation of the difference between throttling and debouncing (complete with graphs!), as well as a few "alternate" modes for each.
Consider that a function can be debounced at either the beginning OR the end of a series of repeated calls. For example, due to the way people type, when "throttling" AJAX requests triggered by keyboard input, you typically want to wait until the user has paused for a moment before submitting the query. On the other hand, when dealing with game input, you may actually want the first—but ONLY the first—keypress, within a given time period, to trigger an action.
And don't forget about basic throttling, which is simply rate-limiting a function so that it executes no more than once every N milliseconds. Throttling is especially useful in normalizing the scroll and resize events in IE and Safari, which are fired far more frequently than in Firefox (which can cause problems if you're doing anything computationally expensive).
@cowboy - I know this technique is called "debouncing" - but in english, fewer developers will know what you mean and throttling, although technically inaccurate, actually is pretty obvious what you're doing - simplicity of specificity
Equally this article: 3 paragraphs, and 8 lines of code - a lazy developer is a happy developer
Hello
thank you for this.
Never thougt it could be called 'debouncing', but I found this - it's awesome little code snippet!:)
cute
Good name = "chocke", or even better jQuery.choke(dn, delay)