This could make your code behave unpredictably, since you don't really know what events will be used or dropped. For something like a drag handler it's probably not an issue, but it's a little hard to reason about a function whose state depends on when the function was last called. You could easily run into a bug where two pieces of code call a trickle'ed function, expecting it to take an action, and encountering a bug when the two calls are too close.<p>If polling is what's needed then it makes more sense to use setInterval and have a better guarantee of when things are being run. Or you could stuff events into a buffer and have a function consume them periodically - either way, when you lose an event it's either 1. irrelevant, because polling only cares about the state at time t and not the events, or 2. deterministic, because your consumer function decided to get rid of it.
This program has a bug.<p>Suppose the user is entering the word "hacker" at .101 seconds per character, and your cooldown time is .3, your code will do something like this:<p><pre><code> t=0.000 : 'h' FIRE
t=0.101 : 'a'
t=0.202 : 'c'
t=0.303 : 'k' FIRE
t=0.404 : 'e'
t=0.505 : 'r'
</code></pre>
If the expensive, rate-limited function is an AJAX call to the server to see if a username is available, for example, you'll want to call again with "hacker" at t=0.6 seconds, not keep displaying the result for "hack" forever.<p>Actually, the expected behavior isn't sufficiently well-specified to determine whether the code implements it. But I believe many applications of such code will need to take care to avoid the behavior I describe.<p>As suggested in another comment, I'd use a setInterval (classic JS) or a separate thread (HTML5 or node.js) to periodically check if the function needs to be run, and if so, run it.
I am doing validation for username and email from JavaScript with the server similar to the way twitter is doing. I have to make sure that I do not bombard my server for each keystroke and mouse click (in case user decides to copy+paste the email address using the mouse). This is how I did. It works so far but as always it can enhanced. I can share the full source but it is the skeleton to give u the idea. In essence I am waiting for 1300 milliseconds before hitting the server again.<p>$(emailTextBoxId).keyup(function (event) {<p><pre><code> //executes a function, once, after waiting a specified number of milliseconds
setTimeout("CheckEmailAddressAvailability()", 1300);
//stopping bubble
return false;</code></pre>
});<p>$(emailTextBoxId).keydown(function (event) {<p><pre><code> safeToPerformEmailCheck = true;
document.getElementById("ValidEmailAdd").style.display = "none";
document.getElementById("ExistingEmailAcc").style.display = "none";
//document.getElementById("InvalidEmailAdd").style.display = "none";
</code></pre>
});<p>$(emailTextBoxId).mouseup(function (event) {<p><pre><code> safeToPerformEmailCheck = true;
CheckEmailAddressAvailability();
</code></pre>
});<p>Edit:
I just saw the examples posted by fellow readers at following links are much better than mine. I am glad I really learned some good stuff today and I will edit my code today as first thing once I go home this eve. Really neat.<p><a href="http://jsbin.com/ejimok/3/edit" rel="nofollow">http://jsbin.com/ejimok/3/edit</a><p><a href="http://jsbin.com/ejimok/5/edit" rel="nofollow">http://jsbin.com/ejimok/5/edit</a>
This is one of the great things about JavaScript and functional programming in general. You can create reusable control flow abstractions easily.<p>Other examples are things like memoizing/caching values, logging, etc.
Google Closure also provides throttling functionality:<p><a href="http://closure-library.googlecode.com/svn-history/r44/docs/class_goog_Throttle.html" rel="nofollow">http://closure-library.googlecode.com/svn-history/r44/docs/c...</a>