When, in special circumstances, we want to prevent a function from being called too often:
Throttling - additional calls to the function are ignored for next n ms.
Debouncing - any call to the function is delayed till n ms have passed since the last call.
Both of these are easy to implement by creating meta-functions that return a wrapped version of original function:
function throttle(func, delay) {
var lastHitDate = 0;
return function() {
var now = new Date();
if(now - lastHitDate >= delay) {
lastHitDate = now;
return func.apply(this, arguments); // call the function if _delay_ ms have passed since last call
};
};
}
function debounce(func, delay) {
var timerId;
return function() {
// everytime the function is called, delay it by _delay_ ms
clearTimeout(timerId);
timerId = setTimeout(function() {
func.apply(this, args);
}, delay);
};
}
Note that with debouncing, the function may never get called if it's called too often - may need to add a max delay. Also note that it's important to use the same throttled/debounced instance of a function from every place that we want to limit calls from. Calling throttle/debounce methods again would just create a new timer/lastHitDate.
Underscore.js provides _.throttle
and _.debounce
.