Friday, June 27, 2014

The Difference Between Throttle and Debounce

I've always wondered what the difference is between the debounce() and throttle() Lodash functions. It turns out, there is no real difference — throttle() depends on debounce(), which handles all the complex logic of timing function execution. So what does throttle(), do exactly? It sets up the leading and the trailing edge of the timeouts.

So, if all you want to do is keep something from running too frequently, I'd stick with throttle() — mainly because I like the function name better. But if you're already using debounce() stick with it. The point is, they're exactly the same. Lastly, I've never had a need to use the trailing option. I'm sure there are some advanced scenarios where it's needed, but for some reason, this is turned on by default. As this example illustrates, you can turn it off and yet keep the code clean.

function obj() {}

obj.prototype.log = _.throttle( function() {
    console.info( 'called log()' );
}, 200, { trailing: false } );

_( new Array( 500000 ) )
    .map( function() {
        return new obj();    
    })
    .tap( function() {
        console.time( 'elapsed' );
    })
    .invoke( 'log' );

console.timeEnd( 'elapsed' );

If we hadn't turned off the trailing option here, there's a chance that log() could be called down the road, will after we've logged the elapsed time. Stuff like this freaks me out, so better to just eliminate the possibility of it ever happening.