Debounce & Throttle 防抖和节流

1,182 阅读2分钟

为什么要限制次数

调整浏览器大小的时候onresize事件会连续触发, 如果在事件函数内部进行DOM操作很可能因为频繁操作造成浏览器崩溃,这个时候就应该限定函数执行次数(不可以在没有间断的情况下连续执行)

而限制次数有两种,一种是延迟n秒(而n秒内重复触发则重新计数),也就是防抖), 一种每隔n秒执行一次,也就是节流

防抖:延迟n秒而n秒内重复触发则重新计数

特点:n秒内执行次数<= 1次,每执行一次时间间隔>=n秒

场景: 比如input 在onChange里面进行搜索,要等所有内容都输入完毕才能执行不然每输入一个值就执行一次, window.resize 等缩放完成再执行相关函数

代码实现:

  • 立刻执行

  • 稍后执行

function debounce(fn, delay) {
  let timer = null;
  return function () {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...arguments), delay);
  };
}

const debounced_fn = debounce(console.log, 1 * 1000);
  • 取消

节流: 每n秒执行一次, 期间重复触发被忽略

就像cs里面开枪点击再快也只能按一定频率开枪

特点n秒内执行次数=1, 每执行一次时间间隔=n秒

场景:点击事件,mousemove,scroll,上拉列表加载数据等

代码实现:

  • 时间戳
  • 定时器版

总结:至于什么时候用防抖什么时候用节流

防抖适合可能频繁触发的事件只结果需要执行一次,尤其是input组件onChange函数里面请求搜索,点击提交按钮onClick事件,其他input.change, onsizechange,而节流适应于刷新更频繁但需要阶段性执行结果的场景比如拖动对话框,要一点点移动过去,而不是拖一段时间不动然后突然弹过去

参考:

冴羽大神的underscore系列

彻底弄懂节流和防抖