用人话说清楚防抖和节流

一、概念:

假设有一个时间间隔time,可以三3秒,可以是两分钟,也可以是五个小时

防抖(Debounce)

一个事件触发 time 时间之后再执行事件回调,如果再等待期间再触发该事件,则重新计时,用吵架来形容的话就是我骂完你2分钟后你才能骂我,如果我再骂你,那你就再等两分钟

节流(Throttle)

在 time 时间内只执行一次事件回调,即使在这 time 时间内触发多次事件,也只执行一次,还是用吵架来说明,就是我可以一直骂你,但是你每隔两分钟才能骂我一次,我停止骂你了你就不能再骂我

二、代码示例:

防抖

这里用到了闭包的概念,timer被暴露出来了,每次调用函数都会重新设置timer,简单一点的实现就是全局设置一个timer, 每次调用函数都重置timer,在Vue中也可以使用组合式函数实现

点击查看代码
function debounce(action, time) {
  let timer = null
  return function(...args) {
    clearTimeout(timer)  // 清除之前的定时器
    timer = setTimeout(() => {
      action.apply(this, args)
    }, time)
  }
}

节流:

这个也是使用的闭包,将lastTime暴露出来,这么做的作用就是不需要收到去设置一个计时变量,同样可以设置全局变量或者组合式函数实现

点击查看代码
function throttle(action, time) {
  let lastTime = 0
  return function(...args) {
    const now = Date.now()
    if (now - lastTime >= time) {
      lastTime = now
      action.apply(this, args)
    }
  }
}

三、使用场景

防抖:

远程搜索,监听用户键盘输入事件,搜索服务器数据,如果不做防抖,用户每输入一个字母或者字符串都会触发一次请求,但在用户输入完成前搜索的结果都不是用户想要的。

点击查看代码
function searchUsersList(keyWord:string): any[] {
   /**搜索用户列表的逻辑 */
   console.log(`搜索用户列表:关键词${keyWord}`);
}

/** 防抖 */
const searchUser = debounce(searchUsersList, 500)

节流:

调整页面上div的大小,或者拖拽调整其在页面上的位置,通常监听的是鼠标位置,鼠标位置每变动一次,都去触发一次逻辑,是没有必要的,只会浪费浏览器性能,且可能因为回调事件还没处理完成就触发新的事件,导致事件堆积。

点击查看代码
function moveDivBox(event:MouseEvent): any[] {
   /**搜索用户列表的逻辑 */
   console.log(`鼠标事件${event.clientX}`);
}

/** 节流 */
const moveDiv = throttle(moveDivBox, 500)

四、总结

防抖:等用户操作停止后再执行(适合搜索、输入)
节流:按固定频率执行(适合滚动、移动)
本质上两种方法都是为了减少事件触发的频率,用来降低资源的消耗,具体场景需考虑实际事件的触发目的,对于只关注最终的结果的用防抖,需要看到中间过程的用节流

posted @ 2025-12-05 14:01  杀鲁班祭天  阅读(1)  评论(0)    收藏  举报