I've written a quick little helper for event & call debounce/throttling. Since I'm at home and none of my regular code review friends are on-line I figured I'd turn to the great folks here! Would love any feedback you might have.
/**
* debounce
* @param {integer} milliseconds This param indicates the number of milliseconds
* to wait after the last call before calling the original function .
* @return {function} This returns a function that when called will wait the
* indicated number of milliseconds after the last call before
* calling the original function.
*/
Function.prototype.debounce = function (milliseconds) {
var baseFunction = this,
timer = null,
wait = milliseconds;
return function () {
var self = this,
args = arguments;
function complete() {
baseFunction.apply(self, args);
timer = null;
}
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(complete, wait);
};
};
/**
* throttle
* @param {integer} milliseconds This param indicates the number of milliseconds
* to wait between calls before calling the original function.
* @return {function} This returns a function that when called will wait the
* indicated number of milliseconds between calls before
* calling the original function.
*/
Function.prototype.throttle = function (milliseconds) {
var baseFunction = this,
lastEventTimestamp = null,
limit = milliseconds;
return function () {
var self = this,
args = arguments,
now = Date.now();
if (!lastEventTimestamp || now - lastEventTimestamp >= limit) {
lastEventTimestamp = now;
baseFunction.apply(self, args);
}
};
};
To help understand what the point of these helpers are I've prepared this demo: http://jsfiddle.net/zR5jV/1/
GitHub project can be found here: https://github.com/m-gagne/limit.js
-
\$\begingroup\$ Honestly, you'd probably be better off just using underscore.js, rather than reinventing the wheel (unless you're doing it for fun). At just around 4K minified, it's a very powerful library that includes more refined versions of both of these methods and is complimentary to almost every other JavaScript library. \$\endgroup\$blesh– blesh2012年04月26日 19:46:58 +00:00Commented Apr 26, 2012 at 19:46
-
\$\begingroup\$ Cool hadn't heard of underscore.js before, thanks. Yes this was more of a "do it for fun" / "try creating a project & associated website" project. It was also more to bring to light the issue of frequency of events that people might not know of. Rarely as a developer do we ever get to create something truly unique, but I've learned a lot and gotten some great feedback in producing this simple snippet of code :) \$\endgroup\$Marc Gagne– Marc Gagne2012年04月27日 15:20:46 +00:00Commented Apr 27, 2012 at 15:20
1 Answer 1
The key differences between a throttled function and a debounced function are that the throttled function can return a value because it is called synchronously and the debounced version cannot because it is used asynchronously.
You have lost that on your throttle implementation. I would at least make the following change:
Function.prototype.throttle = function (milliseconds) {
var baseFunction = this,
lastEventTimestamp = null,
limit = milliseconds,
lastresult;
return function () {
var self = this,
args = arguments,
now = Date.now();
if (!lastEventTimestamp || now - lastEventTimestamp >= limit) {
lastEventTimestamp = now;
lastresult = baseFunction.apply(self, args);
}
return lastresult;
};
};
-
\$\begingroup\$ Good point, I've only used throttle in scenarios where I don't care about the return value. I'll integrate this into my library, thanks! \$\endgroup\$Marc Gagne– Marc Gagne2012年04月25日 12:22:11 +00:00Commented Apr 25, 2012 at 12:22