#43 函数防抖 debounce


  • 0
    administrators

    在前端开发当中,会遇到某个函数被高频率调用的情况。比如说用户疯狂地按住某个按钮,这些事件都会导致回调函数被高频地调用,但是高频调用这些函数可能会导致页面运行效率下降。

    于是就有了一种 debounce 的解决方案:如果你疯狂、高频地调用某个函数,而调用之间的时间间隔低于某个时间段,这个函数最后只会被执行一次;如果高于某个时间段,则会执行多次。

    请你完成 debounce,它接受两个参数,一个是被封装函数,一个是时间间隔(ms),然后返回一个函数。可以做到函数防抖的效果:

    window.addEventListener('resize', debounce(() => {
      console.log('Hello')
    }, 100))
    

  • 0

    刚过 520,周末还在出题啊


  • 0
    administrators

    @Sunjourney 这都被你发现了


  • 0

    @胡子大哈

    感觉这个这个 throttle 和我理解的 throttle 不一样啊。
    而调用之间的时间间隔低于某个时间段,这个函数最后只会被执行一次;如果高于某个时间段,则会执行多次。
    这句话,应该是 debounce 的描述,我理解的 debounce 是延迟执行,多次执行以最后一次为准,用于 search 框较多。resize 确实用 throttle,但应该是每到 throttle 执行最接近 throttle 的一次操作,也就是每过一个 duration,一定会执行一次,而不是 这个函数最后只会被执行一次

    有些 throttle 的实现是 debounce 的效果,但我认为不对,应该按 lodash 的定义来,要不胡子哥把标题改成 debounce ? 用例别用 resize,用搜索框?测试还可以继续用


  • 0
    administrators

    @Sunjourney 对的,是我搞错了。正在修改中


  • 0
    administrators

    @Sunjourney 已经改了描述,感谢建议。


  • 1
    管理员

    思路:debounce里定义一个局部变量timer,再写一个闭包去控制这个timer。
    timer写在闭包外是只执行一次的,而闭包函数在监听过程中是执行多次的。

    const debounce = (fn, duration) => {
      let timer = null;
      return () => {
        clearTimeout(timer)
        timer = setTimeout(() => {
          fn()
        }, duration)
      }
    }

  • 0

    @陈小俊#43 函数防抖 debounce 中说:

    timer = null


  • 0

    @陈小俊 你好,setTimeout的第一个参数为什么外面要多一层匿名函数呢?我不加这个匿名函数也能通过测试用例


登录后回复
 

与 ScriptOJ 的连接断开,我们正在尝试重连,请耐心等待