【前端】一篇搞定节流和防抖,建议⭐

64 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天,点击查看活动详情

前言

作为一道面试常考题,同时也作为前端常见的一个需求/优化性能的解决方案。防抖和节流在前端这条不归路上一直伴随着我,是时候为这俩爷子出一篇文章了。

这篇文章作为节流防抖的使用说明书,主要讲解:

  • **防抖**的使用场景
  • 手动实现一个防抖函数
  • **节流**的使用场景
  • 手动实现一个节流函数

那么,进入正题吧!🤩

**防抖**的使用场景

假设我们在页面上有一个按钮,只要一点击就会触发对应的接口。假设这个接口为保存数据的接口,如果在我们没有做任何操作时,一直点击这个按钮呢?毫无疑问,会连续的多次调用保存接口。然而这种情况不是我们所想要的:

  1. 是无意义的多次调用接口。
  1. 是假设调用完接口有返回提示就会很不美观。

那么现在摆在我们眼前的路就是防抖了。

手动实现一个防抖函数

防抖(debounce :在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。

根据以上条件我们可知:

  • 需要传入一个回调函数
  • 需要使用闭包来保存一个定时器以及限制的时间

GO👇

fucntion debounce(func,time){
    let timer = null
    return ()=>{
        if(timer){
            clearTimeout(timer)
        }
         timer = setTimeout(() => {
            func()
        }, time)
    }
}

**节流**的使用场景

当页面触发drag(拖动)事件或者 scroll(滚动) 时触发某个回调,要设置一个时间间隔。这时候就不能使用防抖了,为什么呢?

防抖是拖拽或者滚动结束之后才返回回调,但是我是需要在过程中进行触发回调,但是又不需要那么的频繁;这时候就使用节流函数,每隔一定的时间进项触发就好了!

手动实现一个节流函数

节流(throttle) :规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。

根据以上条件我们可知:

  • 需要传入一个回调函数
  • 需要使用闭包来保存一个定时器以及限制的时间

GO👇

function throttle(func,time){
    let flag = true
    return ()=>{
        if(flag){
            flag = false
            func()
            setTimeOut(()=>{
                flag = true
            },time)
        }
    }
}

方法二:

function throttle(fn, time) {
    let prev = new Date().now()
    return function () {
        let now = new Date.now()
        if (now - prev >= time) {
            prev = now
            fn()
        }
    }
}

尾声

眨眼一看确实节流函数和防抖函数的实现确实很简单,但有时候理解和手写出来是有些许差异。希望还没掌握的同学,多加练习。