理解节流 & 防抖

概念

节流 (throttle)与 防抖 (debounce)都是为了下降调用频率的一种方式。html

相同点都是须要设置一个回调函数及周期时间,区别在于:react

  • 防抖是在中止触发后的100ms,执行一次(在此时间段内,只要不中止触发,理论上就永远不会触发回调)git

  • 节流是在不断的触发过程当中,每隔100ms就执行一次。github

下面简单画下流程图浏览器

节流 throttle

在高频触发回调函数时,节流操做使回调函数在每隔一段时间按期执行一次,时间间隔内再触发,不会从新执行。markdown

核心在于让一个函数不要执行的太频繁,减小一些过快的操做。less

相似于技能冷却时间 ⏱ide

/** * 节流 * @param func * @param wait */
function throttle(func: Function, wait: number) {
  let timer: number = 0;
  return (...args) => {
    if (timer) { return }
    timer = window.setTimeout(() => {
      func(...args)
      timer = 0
    }, wait)
  }
}
复制代码

防抖 debounce

在高频触发回调函数时,防抖操做使回调函数在必定时间间隔内,再次触发会清空定时器,并从新计时;计时结束后输出一次结果。函数

核心在于,在短期内大量触发同一事件时,只会执行一次回调函数。避免把一次事件误认为屡次。oop

/** * 防抖 * @param func * @param wait */
function debounce(func: ()=>void, wait: number) {
  let timer: number = 0
  return (...args) => {
    clearTimeout(timer)
    timer = window.setTimeout(() => {
      func(...args)
      timer = 0; // 必须么??
    }, wait)
  }
}
复制代码

tips: 注意 args 剩余参数的传递,不然执行回调函数时参数将丢失。

🌰 栗子

// 监听页面滚动条位置
const handleScrollTop = () => {
   const scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
  console.log('滚动条位置:' + scrollTop);
}

// 防抖:在中止滚动100ms后,才会输出滚动条位置
window.onscroll = debounce(handleScrollTop,100)

// 节流:每隔100ms都会输出一次滚动条位置
window.onscroll = throttle(showTop,100) 
复制代码

常见场景

  • 监听 scroll、mousemove 等事件 - 节流(每隔一秒计算一次位置)
  • 监听浏览器窗口 resize 操做 - 防抖(只需计算一次)
  • 键盘文本输入的验证 - 防抖(连续输入文字后发送请求进行验证,验证一次就好)
  • 提交表单 - 防抖(屡次点击变为一次)

节流、防抖有时用哪一个均可以,好比监听页面滚动,能够节流(每一个一段时间出发一次回调),也能够防抖(用户当前此次滚动结束出发,继续滚动等待下一次触发)

React 中使用

  • Class 组件中

须要注意调用节流/防抖函数位置,在组件初始化时就绑定节流/防抖事件,不然回调函数不会被触发。

constructor(props: any) {
  super(props);
  // 注意在此绑定!!
  this.handleScroll = throttle(this.handleScroll, 100)
}
复制代码
  • 在函数式组件中,因为渲染的问题使用起来须要特别注意。能够参考

React hooks 怎样作防抖?

阿里的useDebounce


参考

github.com/jashkenas/u…

github.com/lessfish/un…

linjingyi.cn/posts/7c266…

juejin.cn/post/685457…

相关文章
相关标签/搜索