防抖和节流

23 阅读2分钟
  • 防抖和节流可以避免频繁触发事件导致页面性能下降

  • 防抖(debounce):防止单位事件内,事件触发多次。

    • 代码实现重在重新计时。
    • 业务场景:比如用户重复点击登录按钮,使用防抖,可减少发送登录请求的次数
    • 类似于回城,防抖的原理是只执行最后一次操作,当第一次执行操作后,会判断在delay秒中有没有再次触发,如果有再次触发的话,就会重新计时。所以代码中存在clearTimeOut(time)
    • 应用输入框,用户会持续输入,只有当在一段时间内,没有重复输入后,才将结果发送。
    /**
    * 这里的setTimeout()函数返回是一个数字,代表定时器的id。可以使用clearTimeout(id)来取消定时器
    */
        function debounce(fun, delay) {
            let time = null;
            return function() {
                let that = this;
                let args = arguments;//每一个函数都有一个arguments对象,类数组对象,收集函数的参数,即使()中没有写
                if(time) {
                    clearTimeout(time);
                }
                time = setTimeout(function() {
                    fun.apply(that,args);//这里是匿名函数,匿名函数中的this指向由调用它的对象所决定。setTimeout函数是全局的,this指向window对象。为了使用fun本来的this指向,所以需要借助that。如果是箭头函数,箭头函数的this是由定义箭头函数时的作用域所决定的。
                }, delay);
            }
        }
        
    
  • 节流(throttle):限制单位时间内事件触发的频率。在单位事件内,事件只能触发一次。

    • 代码实现重在开锁和关锁
    • 比如scroll事件,每隔一秒计算一次位置信息
    • 节流:当事件被触发时,函数会立即执行一次,然后在一段时间内(如100ms)内忽略后续的事件触发,直到该时间段过去后再重新执行。
    • 类似于技能CD,在一定间隔时间内只能执行一次,设置定时器,完成操作后,定时器才会置空。代码中需要判断当定时器为空的时候,才能执行操作。否则不做任何操作。
    • 应用在页面滚动中,当页面滚动到底部时,会触发操作,进行加载页面。为避免一直发送请求加载,在一定时间间隔内只会加载一次。
    function throttle(fun, delay) {
        let time = null;
        return function() {
            let that = this;
            let args = arguments;
            if(!time) {//time为空,可以执行操作
                time = setTimeout(() => {
                    fun.apply(that, args);
                    time = null;//操作执行完成之后,重新计时
                }, delay);
            }
        }
    }