Saturday, November 10, 2018

Debounce and throttle function calls in JavaScript


Overview


Looking at debouncing and throttling function calls in JavaScript.

My source code on StackBlitz.com.

Because I am using global variables to keep track of the state, the function debounce() and throttle()
do  not support debouncing and throttling multiple function at the same time.
  • Throttling and Debouncing in JavaScript blog post by Jhey Tompkins
    • Which contains slightly more complicated version of throttle() function than mine.
  • A visual demo by nimius.net : Demo.

Html





JavaScript

  


    let _inThrottleIgnoredCount = 0;
    let _inThrottle = false;

    function throttle(func, limit = 100) {

        return function() {

            const args = arguments;
            const context = this;
            
            if (_inThrottle) {

                // Do not allow the call, just count the number of ignored call
                _inThrottleIgnoredCount += 1;
            }
            else {

                _inThrottle = true; // Do not allow any more call
                _inThrottleIgnoredCount = 0;
                func.apply(context, args); // Make the first call               
                // Set timer for the period for which we will not allow calls
                setTimeout(function () {

                    _inThrottle = false; // Allow call again
                    if(_inThrottleIgnoredCount > 0) { 
                      // If at least one call came during the period for 
                      // which we were not supposed to accept call, then
                      // let's execute the function one last time
                      _inThrottleIgnoredCount = 0;
                      func.apply(context, args); // Call one last time
                    }
                }, limit);
            }
        }
    }
    
    let _inDebounce = null;

    function debounce(func, delay = 100)  {

        return function() {

            const context = this;
            const args = arguments;
            if(_inDebounce !== null) {

                clearTimeout(_inDebounce); // Cancel pending call
                console.log(`Cancel call`);
            }            
            _inDebounce = setTimeout(() => { 

                _inDebounce = null;
                func.apply(context, args);
            }, delay);
        }
    }

    function doSomething() {
        console.log('doSomething');
    } 

No comments:

Post a Comment