zoukankan      html  css  js  c++  java
  • 防抖debounce和节流throttle

    大纲

    一、出现缘由

    二、什么是防抖debounce和节流throttle

    三、应用场景

    3.1防抖

    3.2节流

    一、出现缘由

    前端开发中,有一部分用户行为会频繁触发事件,而对于DOM操作,资源加载等耗费性能的处理,很可能导致卡顿,甚至浏览器崩溃,防抖和节流就是为了这一类的问题出现的前端优化技术。

    二、什么是防抖debounce和节流throttle

    防抖debounce是函数在规定延迟时间内不被调用,才能再次被调用,如果在规定时间内调用,延迟重新开始计算;

    节流throttle是在规定的延迟时间间隔后,函数才执行一次,以固定的频率被触发。

    三、简单实现

    3.1防抖

    连续触发事件的时候,不会有任何反应,停止触发事件的多少秒,就会执行,在延迟时间内执行函数,就重新开始一个定时器。

    function debounce(func,delay=300,timer=null){
        return (...args){
            clearTimeout(timer);
            timer=setTimeout(func.bind(null,...args,delay);)
        }
    }
    function query(){
        //ajax
    }
    input.addEventListener('keyup',debounce(query))
    

      

    3.2节流

    触发事件的时候,执行一个函数,在之后的一段时间内进这个函数,会被return,真正的逻辑不能执行,定时器在一定时间后重置开关,再进来就能再次执行真正的逻辑了。

    function throttle(func,delay=60){
        let lock=false;
        return (...args)=>{
            if(lock)reutrn;
            function(..args);
            lock=true;
            setTimeout(()=>lock=false,delay);
        }
    }
    function query(){
        //ajax
    }
    decument.addEventListener('scroll',throttle(query));
    

      

    四、应用场景

    3.1防抖throttle的应用场景

    防抖适用于window.onscroll事件,等到拉动动作结束后再触发一个事件,或者拖拽

        _.throttle=function(func,wait,options){
            var context,args,result;
            var timeout=null;
            var previous0;
            if(!options)options={}
            var later=function(){
                previous=options.leading===false:0:new Date();
                timeout=null;
                result=func.apply(context,args);
                if(!timeout)context=args=null;
            }
            return fucntion(){
                var now=new Date();
                if(!previous && option.leading===false)previous=now;
                var remaining=wait-(now-previous);
                context=this;
                args=arguments;
                if (remaining <= 0 || remaining > wait) {
                    if (timeout) {
                        clearTimeout(timeout);
                        timeout = null;
                    }
                    previous = now;
                    result = func.apply(context, args);
                    if (!timeout) context = args = null;
                } else if (!timeout && options.trailing !== false) {
                    timeout = setTimeout(later, remaining);
                }
                return result;
            }
        }
    

      

    3.2节流throttle的应用场景

    下面具体讲一个例子

    假设我们网站有一个搜索框,用户输入文本我们自动会联想匹配除一些结果供用户选择,我首先想到的做法是监听keypress事件或change事件,然后ajax请求数据,但是当用户快速输入的时候,就会瞬间触发一连串的请求,这无疑不是我们想要的,我们想要的是用户停止输入的时候才去触发查询的请求,这时候函数防抖可以帮助我们。

    _.throttle=function(func,wait,immediate){
            var timeout,args,context,timestamp,result;
            var later=function(){  //如果没有超过等待时间,就接着设置一个定时器,时间是delay的时间减去方法执行的时间
                var last=new Date().getTime() - timestamp;
                if(last<wait && last>=0){
                    timeout=setTimeout(later,wait-last);
                }else{   //如果已经过wait时间了,就直接清除定时器,给result赋值
                    clearTimeout(timeout);
                    if(!immediate){
                        result=func.apply(context.args);
                        if(!timeout)context=args=null;
                    }
                }
            }
            return function(){
                context=this;
                args=arguments;
                timestamp=new Date().getTime();
                var callNow=immediate && timeout;    //如果是立即执行或者之前执行过还没过延迟时间
                if(!timeout)timeout=setTimeout(later,wait);   //如果之前没执行过,现在开始定时任务,如果执行过,timeout存在,就返回个空的result.
                if(callNow){   //如果是立即执行,就立即执行fn,这时候
                    console.log(1);
                    result=func.apply(context,args);
                    context=args=null;
                }
                return result;
            }
        }
        function query(){
            //ajax
            console.log('ajax');
        }
        $("#search").keypress(_.throttle(query,300));
    

      

  • 相关阅读:
    "std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::str() const"
    Incompatible integer to pointer conversion sending 'NSInteger' (aka 'int') to parameter of type 'id'
    App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app’s Info.plist file
    Bitmasking for introspection of Objective-C object pointers i
    Bitmasking for introspection of Objective-C object pointers
    iOS中常见的报错及解决方案
    Swift3.1
    iOS9使用提示框的正确实现方式(UIAlertView is deprecated)
    IOS8 PUSH解决方法
    栈溢出实践
  • 原文地址:https://www.cnblogs.com/learnings/p/9543782.html
Copyright © 2011-2022 走看看