去抖(debounce)与节流(throttle)

  |   0 评论   |   0 浏览   |   Erioifpud

效果

使用效果参考

See the Pen debounce and throttle by Erioifpud (@erioifpud) on CodePen.

debounce

debounce 也就是我们常说的去抖,用于阻止短时间内的频繁操作

举个例子,页面上有一个刷新按钮,每次点击都会发起请求去获取最新数据,频繁点击会发起多次请求,实际上有意义的只有最后一次,那么阻止“非最后一次”操作这样的行为就是去抖。

去抖函数实现起来非常简单,或许我们在平常的业务中就已经实现过了,但是自己没意识到:

function debounce (func, wait) {
  // 这里做个类型检查
  let timer
  return function (...args) {
    if (timer) {
      clearTimeout(timer)
      timer = setTimeout(() => {
        timer = null
        func.apply(this, args)
      }, wait)
      return
    }
    timer = setTimeout(() => {
      func.apply(this, args)
      timer = null
    }, wait)
  }
}

debounce是一个高阶函数,我们将需要去抖的函数传给他,他返回的就是包装后的函数。

timer记录的是定时器的 id,我们根据这个 id 来判断上一个定时器(时差是否超过 wait)是否执行结束,所以内部函数也使用了这个 timer,这里形成了一个闭包,保证 timer不会因为 debounce执行结束而被回收。

由于 func是在 setTimeout中被调用的,所以在上一个定时器还没完成的时候,需要使用 clearTimeout清除定时器,不然先前的定时器到时间了依然会调用 func

throttle

throttle 是节流的意思,和 debounce 不太一样,虽然也是减少频繁操作的,但他并不会完全阻止操作执行,反而是每隔一定时间放行(执行)一次

举个例子,使用搜索引擎输入关键字的时候会出现自动补全,但并不是每输入一个字网站都会发一个请求去获取候选词列表的,多数是在你保持输入的情况下,每隔 n 秒请求一次,这样的操作就是节流。

function throttle (func, wait) {
  // 这里做个类型检查
  let timer
  return function (...args) {
    if (timer) {
      return
    }
    timer = setTimeout(() => {
      timer = null
      func.apply(this, args)
    }, wait)
  }
}

相比 debouncethrottle的代码就简单很多了,timer还是记录上一个定时器是否执行结束,结束了就可以开始一个新的计时器,没结束就等待。


标题:去抖(debounce)与节流(throttle)
作者:Erioifpud
地址:https://blog.doiduoyi.com/articles/1606098274889.html

评论

发表评论