Input Debounce vs Throttle
by Bart Kalisz
HTML
<input id="q" type="text" autocomplete="off"/>
<pre>
<span>THR: </span><span id="throttled"></span>
</pre>
<pre>
<span>DEB: </span><span id="debounced"></span>
</pre>
JavaScript
var helpers = {
/**
* debouncing, executes the function if there was no new event in $wait milliseconds
* @param func
* @param wait
* @param scope
* @returns {Function}
*/
debounce: function (func, wait, scope) {
var timeout;
return function () {
var context = scope || this, args = arguments;
var later = function () {
timeout = null;
func.apply(context, args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
},
/**
* in case of a "storm of events", this executes once every $threshold
* @param fn
* @param threshhold
* @param scope
* @returns {Function}
*/
throttle: function (fn, threshhold, scope) {
threshhold || (threshhold = 250);
var last,
deferTimer;
return function () {
var context = scope || this;
var now = +new Date,
args = arguments;
if (last && now < last + threshhold) {
// hold on to it
clearTimeout(deferTimer);
deferTimer = setTimeout(function () {
last = now;
fn.apply(context, args);
}, threshhold);
} else {
last = now;
fn.apply(context, args);
}
};
}
}
var input = document.getElementById('q');
var throttled = document.getElementById('throttled');
var debounced = document.getElementById('debounced');
var delayMS = 200;
var setDebounced = helpers.debounce(function(value) {
debounced.innerText = value;
}, delayMS);
var setThrottled = helpers.throttle(function(value) {
throttled.innerText = value;
}, delayMS);
input.addEventListener('input', function(event) {
setDebounced(event.target.value);
setThrottled(event.target.value);
});