关于防抖和节流,你不得不知道

52 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情

为了你能更好的理解节流和防抖,可能需要你对这些知识有一定的理解:this,作用域,定时器

前言

关于防抖和节流,其实都是为了防止接口在一个时间段内频繁的调用。

本文试着从概念到代码的思路去理解防抖和节流。

理解

什么是防抖和节流?

英雄联盟玩过吧?王者荣耀玩过吧?回城懂吧?技能冷却时间懂吧?

如果你都懂,那么先恭喜你,你对防抖和节流的理解就完全是张飞吃豆芽——小菜一碟

防抖: 就是你回城的时候,多次点击回城键,在回城的时间内,只有最后一次才能成功

节流: 就是你在释放技能的时候,技能会进入冷却时间,在这段冷却时间内就不能再次使用


怎么样?是不是很简单?

进一步理解防抖(debounce)

防抖函数的关键是什么?

结合回城去理解,就是在回城这段时间内,如果再次点击,回城的时间就会重新计算,只有最后一次点击才会成功

回到我们代码层面,对于时间的控制,我们需要一个定时器去控制事件触发,当再次触发这个函数的时候,再次激活定时器,并且清除之前的定时器在第二次触发之前

思路步骤:

  1. 传入目标事件,防抖时间
  2. 清除之前的定时器,防止同时有多个定时器
  3. 开启一个定时器
  4. 接收事件的参数
  5. 在定时器中执行目标事件,需要改变this的指向

代码:

function debounce(fun, time) {
    let timer  
    return function() {
        clearTimeout(timer)             // 清除之前定时器
        let args = arguments            // 参数
        timer = setTimeout(() => {      // 设置定时器,延迟回调
            fun.apply(this, args)       // 在定时器中执行目标事件,并且改变this的指向
        }, time)
    }
}

进一步理解节流(throttle)

防抖函数的关键是什么?

结合放技能去理解,就是在放完了技能这段时间内,如果再次点击,技能不会再触发,只有第一次点击才会成功触发

回到我们代码层面,对于时间的控制,我们可以使用定时器,也可以我们手动计时(这次我们以手动计时为例子),第一次触发之后,在这段时间之内都不能再次触发

思路步骤:

  1. 传入目标事件,节流时间
  2. 设置一个初始时间
  3. 获取当前时间
  4. 比较设置的节流时间和经过的时间
  5. 如果经过的时间比设置的时间长,则触发目标函数
  6. 改变this指向,执行目标函数

代码:

function throttle(fun, time) {
    let t1 = 0                          // 设置初始时间  
    return function() {
        let t2 = new Date()             // 获取当前时间
        let args = arguments            // 参数
        if (t2 - t1 > time) {           // 如果经过时间大于设置时间,则执行
            fun.apply(this, arguments)  // 在定时器中this指向window,利用apply改变this指向
        }
    }
}

总结

其实防抖和节流理解之后并不难,希望大家都能理解