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);
});