解决函数的高频次调用的问题,防抖/节流函数

问题

常见的问题就是函数的高频次调用,会极度消耗性能,严重的会把浏览器拖垮,卡死,最常见的是浏览器的窗口大小变化,输入框查询数据库,所以我们有必要限制函数的调用频次,同时确保他不影响用户体验。

解决

函数节流(throttle)函数防抖(debounce)都是为了限制函数的执行频次,以优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟,假死或卡顿的现象。

函数防抖(debounce)是函数先执行,等待n毫秒后,再执行,如果在等待这n毫秒期间,又调用此方法,就会打断,重新计算(也就是重新等待n毫秒)后执行;就像坐电梯一样,有人在一定的时间内按了就重新等待设置的时间,等没有人在上的时候才执行。

函数节流(throttle)是我先设定一个等待周期,等待周期结束后执行函数,中间不受影响,执行完函数后,进入下一个等待周期;就像地铁一样,每站等待3分钟,3分后,开车,进入下一站。

防抖函数和节流函数的应用场景:

1.window对象的resize、scroll事件
2.拖拽时的mousemove事件
3.文字输入、自动完成的keyup事件

实现

函数防抖(为了防止他一直触发,我们制定一个时间限制time,让它的执行时间间隔大于时间限制就主动执行)

 /**
         * fn执行函数
         * wait 函数执行等待时间(电梯从开门到关门的设定时间)
         * time 函数时间间隔(限制电梯从开门到关门的实际时间,防止他一直触发不会执行。)
         * 
         */

        function _debounce(fn,wait,time){
            var previous=null;//记录上一次运行的时间
            var timer=null;
            return function(){
                var = +new Date();//记录当前时间
                if(!previous) previous = now;
                //当上一次执行的时间与当前的时间差大于设置的执行间隙时长的话,就主动执行一次
                if(now -previous > time){
                    clearTimeout(timer);
                    fn();
                    previous = now;//执行函数后,马上记录当前时间
                }else{
                    clearTimeout(timer);
                    timer = setTimeout(function(){
                        fn();
                    },wait);
                }
            }
        }
        function _log(){
            console.log(1);
        }
        window.onscroll = _debounce(_log,500,2000)

函数节流(每隔time执行一次函数,在time未执行完的时,函数不执行,直接返回;)

  /**
         * 函数节流
         * fn 执行函数
         * time 函数执行指定时间间隔
         */
        function _throttle(fn,time){
            let _self=fn,
            time,
            firstTime=true;//记录是否是第一次执行的flag
            return function(){
                let args= arguments,//解决闭包传参问题
                _me=this//解决上下文丢失问题
                if(firstTime){//若是第一次,则直接执行
                    _self.apply(_me,args)
                    return firstTime = false
                }
                if(timer){//定时器存在,说明有事件监听器在执行,直接返回
                    return false
                }
                timer =setTimeout(function(){
                    clearTimeout(timer)
                    timer= null
                    _self.apply(_me,args)
                },time || 500)

            }

        }
        function _log(){
            console.log(1);
        }
        window.onscroll = _throttle(_log,500,2000)

我自己的理解

节流节流的概念就是这样子的,比如你在那个input框输入数字,输入一个查询条件吧,然后这个条件会实时传入后端,就是说实时监听,只要input框的数值发生变化的时候,他就会去后端去请求。那么问题来了,你如果写数字的话,123456789。你从一输入到九,这块儿是不是要变化九次,那么每变化一次,都会去后台请求数据。但对性能来说,你已经请求了9次,但你正常,你只需要拿到最后一条数据,就行了。那么你请求九次,那其他的8次其实都是多余的,这就是节流的概念,节流的概念就是去除那些不要的,比如最简单的理解,就是做个延迟。

防抖比如说你在改变div宽高的时候,他就会去执行一个函数,当你拖动那个浏览器大小的时候,那个div的宽高会不停地会发生变化,而且那个数值会很快,他就会一直在去执行这个函数。然后你需要的只是他停下来的那一瞬间去执行。所以说这也可以加延迟,就是节流防抖,不外乎就是一个概念:等,等一会儿不操作,或者是稍微卡的一段时间,就是0.5秒这样子。其实。从那个人的体验角度来说,并没有停顿很长时间,但是从性能角度来说,已经被服务器省下了很多的那个处理空间。

你可能感兴趣的:(解决函数的高频次调用的问题,防抖/节流函数)