防抖(debounce) &&节流(throttle)

136 阅读2分钟

防抖

在事件被触发n秒后再执行回调,如果n秒内事件又再次被触发就重新开始的计时。只执行最后一次。

image.png

手写简版

function debounce (fn,wait){
    var timer = null;
    
    return function(...args){
        // 如果此时存在定时器的话,则取消之前的定时器重新记时
        if(timer){
            clearTimeout(timer);
        }
        
        // 设置定时器,使事件间隔指定事件后执行
        timer = setTimeout(()=>{
            fn.apply(this,args);
        },wait);
    };
}

适用场景:

  • 文本输入的验证,连续输入文字后发送 AJAX 请求进行验证,验证一次就好
  • 按钮提交场景:防止多次提交按钮,只执行最后提交的一次
  • 服务端验证场景:表单验证需要服务端配合,只执行一段连续的输入事件的最后一次。

节流

规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。意思是每个一段时间执行一次

image.png

手写简版

function throttle (fn,wait){
    var preTime = Date.now();
    
    return function(...args){
        var nowTime = Date.now();
        // 如果两次时间间隔超过了指定时间,则执行函数。
        if(nowTime-preTime >= wait){
            preTime = Date.now();
            return fn.apply(this,args);
        }
   };
}

适用场景:

  • 拖拽场景:固定时间内只执行一次,防止超高频次触发位置变动。DOM 元素的拖拽功能实现(mousemove
  • 滚动场景:监听滚动scroll事件判断是否到页面底部自动加载更多
  • 动画场景:避免短时间内多次触发动画引起性能问题

总结:

函数防抖:限制执行次数,多次密集的触发只执行一次。

  • 原理是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。

函数节流:限制执行的频率,按照一定的时间间隔有节奏的执行。

  • 原理是通过判断是否到达一定时间来触发函数。