写一个debounce函数

这里尝试写一个debounce函数的过程。

debounce是什么?就是防抖动,假设我们监听了输入框的change事件,绑定了一个函数来验证,那么我们在输入的过程中就会不断触发这个函数,很多时候我们其实不想这个函数触发得这么频繁,因为用户都是不断输入的,没必要不断验证,我们真实希望的是,用户停止的时候才触发这个函数,所以我们希望给一个delay的时间,在这个时间内,不断触发的函数,也只按最后一次来触发。

就好像上图那样,只要你触发后面,如果不超过delay时间再次触发的话,也会继续等,直至最后一次触发超过delay的时间,函数才执行一次,很好理解。

当然了,如果希望的是立即执行函数的话,情况就会是下面这种情况:

只要你触发的时间比上次函数执行时间超过了delay的时间,就会被立即执行。

这里写的debounce函数就不考虑立即执行这种情况,按前面的情况来写一下。

首先,这个函数名称就叫做debounce,这个函数接受两个参数,一个是防抖执行的函数,一个是延时delay的时间,所以我们会用到setTimeout这个方法,而且我们执行了debounce之后需要返回一个被触发的函数,考虑到我们需要,会先有:

function debounce(fn, delay) {
  let _fn = fn  //保存函数的引用
  return function(){
    let _self = this
    let args = arguments
    setTimeout(function(){
      _fn.apply(_self, args)
    }, delay)
  }
}

这样执行下来,也只不过每个函数都执行一次延时而已,还没达到我们想要的效果,所以我们还需要做的是,这个函数在delay时间内,也就是还没执行前,再次触发的话,就将上一次设定的延时器清除,那这就容易增加代码为:

function debounce(fn, delay) {
  let _fn = fn  //保存函数的引用  
  let timer
  return function(){
    clearTimeout(timer)
    let _self = this
    let args = arguments
    timer = setTimeout(function(){
      _fn.apply(_self, args)
    }, delay)
  }
}

这就基本实现了debounce函数了,其实就是利用了一个闭包的形式,将原本的timer保存起来,只要函数还没执行(也就是delay时间内)再次触发的话,就会先清除了前一个的timer了,基本实现了防抖的效果。

发表评论

电子邮件地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据