什么是防抖/节流

  • 防抖(debounce):触发高频事件后 n 秒内函数只会执行一次,如果 n 秒内高频事件再次被触发,则重新计算时间;我们日常使用的百度搜索框就使用了防抖机制,只有在输入框不再输入内容一段时间之后才会弹出关键词索引
  • 节流(thorttle):高频事件触发,但在 n 秒内只会执行一次;例如滑动到底部自动加载下一页,就可以通过节流来控制

区别:防抖只会在最终执行一次;而节流是每隔一段时间执行一次,起到稀释操作的作用

image-20210216164620319

这里借用一张网络上的图片,前半部分节流,只会在某一时间点触发,可以看见a、b、c三个点在时间线上都是一样的;后半部分是防抖,a事件过了一段时间之后触发,b、c事件之间的间隔没有达到阈值,c事件就会覆盖b事件,最终只有c事件执行

为什么要防抖/节流

事件无法控制触发频率,会不断执行事件造成性能的浪费,比如鼠标位置、页面滚动……等,使用了防抖或节流就可以有效的控制不可控事件的触发,可以优化用户体验,甚至可以缓解服务器压力

怎样实现防抖/节流

防抖

通过不断地重置计时器timer来实现最终只执行一次

/**
 * @description: 函数防抖,利用闭包返回防抖函数
 * @param {*} fun 需要防抖的函数
 * @param {*} wait 等待时间,默认0.5秒
 * @return {*} 实际到用的防抖函数
 */
function debounce(fun, wait = 500) {
  let timer = null

  return function (...args) {
    if (timer) {
      clearTimeout(timer)
    }
    timer = setTimeout(() => {
      fun.apply(this, args)
    }, wait)
  }
}

节流

通过setTimeout执行事件来调控状态位

/**
 * @description: 函数节流
 * @param {*} fun 需要节流的函数
 * @param {*} wait 等待时间,默认0.5秒
 * @return {*}
 */
function throttle(fun, wait = 500) {
  let valid = true
  return function (...args) {
    if (!valid) {
      return false
    }
    // 工作时间,执行函数并且在间隔期内把状态位设为无效
    valid = false
    setTimeout(() => {
      fun.apply(this, args)
      valid = true
    }, wait)
  }
}

前端小白