Underscore debounce vs vanilla Javascript setTimeout

前端 未结 4 2152
有刺的猬
有刺的猬 2021-02-08 19:20

I understand that debounce in Undercore.js returns a function that will postpone its execution until the wait time is over.

My question is, is there an adva

4条回答
  •  半阙折子戏
    2021-02-08 19:42

    You can also implement your own debounce in vanilla JavaScript. A widely quoted article is David Walsh's article on function debouncing with underscore which includes the source code used by underscore in their implementation:

    // Returns a function, that, as long as it continues to be invoked, will not
    // be triggered. The function will be called after it stops being called for
    // N milliseconds. If `immediate` is passed, trigger the function on the
    // leading edge, instead of the trailing.
    function debounce(func, wait, immediate) {
        var timeout;
        return function() {
            var context = this, args = arguments;
            var later = function() {
                timeout = null;
                if (!immediate) func.apply(context, args);
            };
            var callNow = immediate && !timeout;
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
            if (callNow) func.apply(context, args);
        };
    };
    

    The debounce function serves as a generator for the actual function you'd like to call, that way the state can be persisted inside of the closure like this:

    // example function
    let sayHello = (name) => console.log(`Hi ${name}`)
    
    // generate a debounced version with a min time between calls of 2 seconds
    let sayHelloDebounced = debounce(sayHello, 2000)
    
    // call however you want
    sayHelloDebounced('David')
    

    Demo in Stack Snippets

    function debounce(func, wait, immediate) {
    	var timeout;
    	return function() {
    		var context = this, args = arguments;
    		var later = function() {
    			timeout = null;
    			if (!immediate) func.apply(context, args);
    		};
    		var callNow = immediate && !timeout;
    		clearTimeout(timeout);
    		timeout = setTimeout(later, wait);
    		if (callNow) func.apply(context, args);
    	};
    };
    
    let sayHello = (name) => console.log(`Hi ${name}`)
    
    let sayHelloDebounced = debounce(sayHello, 2000)
    
    sayHelloDebounced('David')
    sayHelloDebounced('David')
    sayHelloDebounced('David')

    Other Implementations

    • Underscore Docs | Underscore Source
    • Lodash Docs | Lodash Source
    • 30 Seconds of Code

提交回复
热议问题