JavaScript中函数节流与防抖

146 阅读2分钟

一、对防抖的理解

触发完事件 n 秒内不再触发,才执行;如果n秒内事件再次被触发,则重新计算时间
如: 设置某个函数2s钟内只能执行一次,如果2s内实际触发了大于2次,则2秒内不会执行,会等到最后一次触发结束2s后执行;

function debounce(fn,delay = 100){
    // 创建一个标记用来存放定时器的返回值
    let timer = null  
    return function (){
        // 每当事件触发的时候把前一个 setTimeout清除
        if(timer) clearTimer(timer) 
        // 然后又创建一个新的 setTimeout, 这样就能保证时间间隔内如果事件持续触发,就不会执行 fn 函数
        timer = setTimeout(() => {
            fn.apply(this,arguments)
            timer = null
        },delay)
    }
}

二、函数防抖应用场景:

搜索框输入查询,如果用户一直在输入中,没有必要不停地调用去请求服务端接口,等用户停止输入的时候,再调用,设置一个合适的时间间隔,有效减轻服务端压力
scroll 事件滚动触发事件,scroll一直滚动,则不输出,若停止移动,则1S后输出一次
手机号、邮箱验证输入检测
窗口大小Resize。只需窗口调整完成后,计算窗口大小。防止重复渲染

三、函数节流理解:

持续触发事件,每隔一段时间,只执行一次事件(类似于技能冷却时间)
如: 设置某个函数2s钟内只能执行一次,如果2s内实际触发了大于2次,那最多只能执行1次;

function throttle(fn,delay = 100){
  // 通过闭包保存一个标记,相当于一个开关
  let flag = true
  return function () {
    // 在函数开头判断标记定时器是否触发,如果有值return
    if (!flag) return
    flag = false
    setTimeout(() => {
      fn.apply(this, arguments)
      flag = true
    }, delay)
  }
}
12345678910111213

四、函数节流的应用场景:

高频点击提交,表单重复提交
搜索联想
DOM 元素的拖拽功能实现
计算鼠标移动的距离

五、节流与防抖相同点和区别:

他们都是可以防止一个函数被无意义的高频率调用
都可以通过使用 setTimeout 实现
函数节流:是确保函数特定的时间内至多执行一次
函数防抖:是函数在特定的时间内不被再调用后执行