JavaScript: Anti-shake and throttling, do you know about it?

JavaScript: Anti-shake and throttling

One, anti-shake

  • Definition: The function will only be executed once within n seconds after the start of the high-frequency event. If the high-frequency event occurs again within n seconds, the time will be recalculated.

  • Implementation idea: Set a delayed call method every time an event is triggered, and cancel the previous delayed call method;

  • Disadvantage: If the event is triggered continuously within the specified time interval, the calling method will be continuously delayed.

// 简易版
function debounce(fn){
    
    
    let timeout = null;
    return function(){
    
    
        clearTimeout(timeout);
        timeout = setTimeout(()=>{
    
    
            fn.apply(this,arguments);
        },1000);
    }
}

function handle(){
    
    
    console.log(this);
}

window.onmousemove = debounce(handle);
  • The simple version has a disadvantage: when the event is called, the this object always points to the window (because it is in the closure), so we can store the context in the closure first;
// 高级版
function debounce(func, wait, immediate){
    
    
    var timeout, result;   
    let decounced = function(){
    
    
        //改变内部this指向
        let context = this;
        let args = arguments;
        clearTimeout(timeout);
        if(immediate){
    
    
            let callNow = !timeout;
            timeout = setTimeout(() => {
    
    
                timeout = null;
            }, wait);
            //表示立即执行
            if(callNow) result = func.apply(context, args);

        }else {
    
    
            //不会立即执行
            timeout = setTimeout(function(){
    
    
                result = func.apply(context, args);
            }, wait);
        }
        return result;
    }
    decounced.cancel = function(){
    
    
        clearTimeout(timeout);
        timeout = null;
    }
    return decounced;
}

function handle(){
    
    
    console.log(this);
}

window.onmousemove = debounce(handle,1000,true);

Second, throttling

  • Definition: triggered by a high-frequency event, but it will only be executed once in n seconds, over 100 million throttling will dilute the execution frequency of the function;
  • Implementation idea: When the event is triggered, if there is currently a delay function waiting to be executed, return directly;
// 简易版
function throttle(fn){
    
    
    let canRun = true;
    return function(){
    
    
        if(!canRun) return;
        canRun = false;
        setTimeout(()=>{
    
    
            fn.apply(this,arguments);
            canRun = true;
        },1000);
    }
}

function handle(){
    
    
    console.log(Math.random());
}

window.onmousemove = throttle(handle);
  • The same problem, the simplified version of this points to window;
// 高级版
// options传入一个对象,表示模式
//{
    
    
//	leading : true/false,
// 	trailing : true/false
//}
function throttle(fn,wait,options){
    
    
    let context,args,timeout,result;
    let old = 0;
    if(!options) options = {
    
    };
    
    
    let throttled = function(){
    
    
        context = this;
        args = arguments;
        let later = function(){
    
    
            old = new Date().valueOf();
            timeout = null;
            result = fn.apply(context,this);
        }
        
        let now = new Date().valueOf();
        if(options.leading === false && !old){
    
    
            old = now;
        }
        if(now - old > wait){
    
    
            //头部执行
            if(timeout){
    
    
                clearTimeout(timeout);
                timeout = null;
            }
            result = fn.apply(context,args);
            old = now
        }else if(!timeout && options.trailing !== false){
    
    
            //尾部执行
            timeout = setTimeout(later,wait);
        }
        return result;
    }
    
    
    throttled.cancel = function(){
    
    
        clearTimeout(timeout);
        old = 0;
        timeout = context = args = null;
    }

    return throttled;
}
function handle(){
    
    
    console.log(Math.random());
}

window.onmousemove = throttle(handle,1000,{
    
    
	leading : true,
	trailing : false
});

Three, the difference

  • No matter how frequently the event is triggered, the throttling guarantees that the event function will be executed once within the specified time;
  • Anti-shake only triggers a function in the last event;

Four, applicable scenarios

  • Anti-shake
  1. The scroll event is triggered by scrolling, such as setting when the icon back to the top appears
  2. Enter the query in the search box, and search again when the user pauses after inputting (fuzzy search)
  3. Form validation, real-time detection when the user pauses after input
  4. Button submit event to prevent violent click from sending multiple requests
  5. Browser window zoom, resize event
  • Throttling
  1. Realization of the drag and drop function of DOM elements
  2. shooting game
  3. Calculate the distance moved by the mouse
  4. Listen to scroll events

Guess you like

Origin blog.csdn.net/yivisir/article/details/108041603