手写防抖与节流

112 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情

前言

防抖节流面试经常遇到,今天就手写一个

防抖

防抖就是多次触发事件,但是事件函数只触发一次,并且是最后一次触发事件时触发

也就是说一个点击事件,如果在规定时间内多次触发,那么他只会触发最后一次点击,其他事件不触发

也就是说,我们可以添加一个按钮,给他绑定点击事件,让事件函数在2s后执行,如果2s内再次点击,则取消执行,让后再添加新的事件

const but = document.querySelector("button")
let timer = ""
but.addEventListener("click", () => {
    clearTimeout(timer)
    timer = setTimeout(() => {
        console.log("but被点击");
    }, 2000)
})

防抖.gif 我们可以把防抖抽取成一个函数


function vibrationProof(fn, thisTime) {
    let timer = ""
    return function() {
        clearTimeout(timer)
        timer = setTimeout(() => {
            fn()
        }, thisTime)
    }
}

防抖函数.gif

函数vibrationProof接收两个参,一个回调,一个延迟时间,函数执行是让timer为空(因为在添加点击事件回调函数时,会先把回调执行,我们在这个时候初始化一个timer),函数返回一个匿名函数,先取消定时器,再添加定时器

节流

节流就是在规定时间内,事件函数只能执行一次且是第一次

或者是在事件函数执行完成后,才能再次触发


let flag = true
const but = document.querySelector("button")
but.addEventListener("click", () => {
    if (flag) {
        flag = !flag
        setTimeout(() => {
            console.log("btn被点击");
            flag = !flag
​
        }, 2000)
    }
})

节流.gif

定义变量flag管理函数执行的状态,当被点击,先判断flag的状态,为true则把flag变成false,这样再次点击则不会执行时间函数,当函数执行完成,把flag状态变为true,方便下次接着执行

可以看到,不论我点击多少次,2s内只执行最开的那次点击

封装成函数


function throttlev(fn, thisTime) {
  let flag = true
  return function() {
      if (flag) {
          flag = !flag
          setTimeout(() => {
              flag = !flag
              btnClick()
          }, 2000)
      }
  }
}

定义一个函数throttlev,接收两个参数,回调和时间,当函数执行,返回一个匿名函数,匿名函数根据flag的值判断是否继续执行,并且在函数执行完成后把flag更改为true,方便下一次执行

节流函数.gif

结束

希望大家都有所收获,那么就点个赞吧,谢谢