JS的防抖和节流

JS的防抖和节流

前几天在面试的过程中有被问到在监听input输入事件向后台传递数据的时候要怎么优化,由于之前并没有关注性能这一块儿的问题(之前在学redis的时候有了解过使用redis做cache)于是就胡乱答了使用缓存。然后面试官前辈就提示我可以使用JS中的防抖(PS:面试全程非常nice,有回答不对的地方面试官都给我做了指正,感觉就像是在和前辈讨论技术问题),之后我也有查阅相关资料,今天我们就来讨论一下防抖和节流

1. 防抖

  • 含义:

    防抖,即在某一段时间内函数只执行一次,如果在这一段时间内又触发了该时间则会重新计算函数的执行时间

  • 举个例子:

    比如有个函数

    1
    2
    3
    function print() {
    console.log(arguments)
    }

    现在需要把这个函数绑定到window.onkeypress事件上

    1
    window.onkeypress = print

    现在每按一下键盘按键都会打印出”hello”,然后我们对其改装

    1
    2
    3
    4
    5
    6
    7
    function shake(func, time) {
    let timeout
    return function () {
    if (timeout) clearTimeout(timeout)
    timeout = setTimeout(() => { func() }, time)
    }
    }

    现在我们将shake这个函数绑定到window.onkeypress事件上

    1
    window.onkeypress = shake(print, 1000)

    现在我们再试试,发现在一个时间段内按压多个按键的时候只打印了一次”hello”,这就是一个简单的防抖实现

  • 类型:

    • 延迟执行版

      在上面的例子中我们简单实现了一个延迟执行的防抖函数,但还没有完全实现,我们还没有将事件的参数传进去,下面我们将其补充完整:

      1
      2
      3
      4
      5
      6
      7
      8
      function shake(func, time) {
      let timeout
      return function () {
      let args = arguments
      if (timeout) clearTimeout(timeout)
      timeout = setTimeout(() => { func.apply(this, args) }, time)
      }
      }

      我们使用apply方法指定函数的执行上下文(this)和参数,该版本不会立即执行函数,而是在触发事件一段时间后再去执行该函数,如果在这段时间内又触发了时间则会重新计算时间

    • 立即执行版

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      function shake(func, time) {
      let timeout
      return function () {
      let args = arguments
      if (timeout) clearTimeout(timeout)
      let call = !timeout
      timeout = setTimeout(() => {
      timeout = null
      }, time)
      if (call) func.apply(this, args)
      }
      }

      该版本在事件触发后会立即执行,经过一段时间不触发事件后才能继续执行

2. 节流

  • 含义

    连续触发事件但是在一段时间内只执行一次函数。节流会稀释函数的执行频率。

  • 版本

    • 时间戳版

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      function throttle(func, time) {
      let then = 0
      return function() {
      let now = Date.now()
      let args = arguments
      if (now - then > time) {
      func.apply(this, args)
      then = now
      }
      }
      }
    • 定时器版

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      function throttle(func, time) {
      let timeout = 0
      return function() {
      let now = Date.now()
      let args = arguments
      if (!timeout) {
      timeout = setTimeout(() => {
      func.apply(this, args)
      timeout = null
      }, time)
      }
      }
      }

以上我们就简单的实现了一下防抖和节流,又get到了一个点,在这里还是很感谢那位前辈的。

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • © 2019-2021 musi

请我喝杯咖啡吧~

支付宝
微信