适合新手:关于函数防抖与节流的理解

663 阅读3分钟

函数防抖的实现

函数防抖,是指仅仅在设定的时间内只执行你的最后一下操作,之前的都会被清空。

比如在输入框连续输入100个字符,那么就会利用变量是否为null进行100次的判断,

如果变量不是null 就证明已经执行过一次并且将setTimeout赋值给了timeoute(此时非null),

所以就会清空上一次的timeout,而本次点击的不会被清空,会在设定的时间后执行,

如果在设定的时间内又再次触发了,那么就会继续清空上次的timeout,再等待本次的多少秒后执行, 这就是函数防抖的定义

  debounce(func,time){
    let timeout = null
    return function () {
      if (timeout) clearTimeout(timeout)
      timeout = setTimeout(() => {  // 判断是否为null 如果不为null 就证明已经执行过setTimeout 并进行了赋值,但是由于setTimeout 是延迟 执行所以还没真正执行里面的函数,而此时你又触发了并且判断timeout 已经不再是null,所以就会清空timeout
        func.call(this,arguments)
      }, time)
    }
  }

函数节流的实现

第一种方式:

函数节流,是指仅仅在设定的时间内,不管是操作多少次,也只触发一次

比如点击按钮,当你进行点击事件请求接口,首先声明变量存存储点击记录,如果,变量是null,证明没有被点击,那么就可以触发setTimeout并且存储到变量记录了点击,

如果频繁的点击,那么因为变量存储了点击记录不为null,所以不会再次执行判断里的语句,而在定义的时间结束后,

执行了上一次被记录的点击事件,此时变量已被赋值为null, 此时再次点击才会被重新记录,然后在定义的时间后再次执行,以此往复

    let timeout = null
    return function () {
      if(!timeout){
        timeout = setTimeout(()=>{
          func.call(this,arguments)
          timeout = null
        },time)
      }
    }
  }

第二种方式:

不再使用setTimeout 的延迟执行,而是利用当前执行时的时间(new Date.now())和上一次执行时间的相差值进行比较判断是否大于设定时间

如果判断成立,再执行,判断不成立就不执行,和第一种的区别是判断的是时间差,而第一种是利用setTimeout 的延迟执行 进行变量的改变进行判断

throttle(func,time){
    let per = 0 // 定义前一次时间用来进行比较用
    return function(){
      let now = Date.now() // 存储当前调用时间
      if(now - per > time){ // 判断当前调用时间减去上次调用时间的间隔大于 设定时间 即执行函数
        func.call(this,arguments)
        per = now // 记录当前调用时间
      }
    }
  }

函数防抖和函数节流的区别(注意)

函数防抖是让函数只可执行最后一次,所以使用setTimeout 必须要清除的,否则还是会被执行,

函数节流是让函数在时间内只可执行一次,不是不让函数执行,所以使用setTimeout 实现 无需清除

东西简单,第一次写,如有不对,请各位高抬贵手,给予纠错,谢谢!!!