JS debouncing
27 Feb

JS debouncing

  Let us say you have a rather expensive ajax call that you want to make only when necessary, but you also need it to be bound to a mouseover event. How do you gauruntee that it will only be called once? What if the user hovers multiple times? What if it is a very UI intensive operation that needs to be triggered. How do you delay until they have come to rest on what you are sure is the item they want? The solution is actually fairly simple. It is called debouncing.

  I first ran accross this issue many years ago in a javascript control I was writing. My solution then was to create a lock object and clear the lock when I was sure the call was safe to procede. Although not far off from the solution I have settled on today, this process was cumbersome and required global state, so it was more of a hack then a desireable final solution.

Javascript

SetLoading: function () {
    this.Lock.isLoading++;
},
ClearLoading: function () {
    this.Lock.isLoading--;
    if (!this.Lock.isLoading) {
        // all calls are finished
    }
},

  Recently I have discovered the concept of debouncing. Debouncing involves using a setTimeout in collaboration with clearTimeout to simply cancel the current call and send a new one when a confilicting event is triggered. Underscore and other JS frameworks have debounce functions built in, but the logic is simple enough to write on your own.

Javascript

var delay = (function () {
    var timer = 0;
    return function (callback, ms) {
        clearTimeout(timer);
        timer = setTimeout(callback, ms);
    };
})();

delay(function() {
    // your expensive or non-threadsafe call
});

  I have used this code in several places recently to delay expensive ajax on frequent events and to solve race issues. It has become my javascript hammer. Even right now I can think of several "nails" in my code that are in need of hammering.