轻松手写防抖和节流

126 阅读2分钟

防抖

顾名思义,我们可以将防抖理解为是防止抖动。当我们在频繁地触发一个事件时,会引起不必要的性能损失,那么我们需要做的是让事件在停止触发后再触发,以此减少性能损失。

防抖就是要延迟执行,我们一直操作触发事件并且不执行,只有当停止操作后等才会执行。

防抖函数 的作用是控制函数在一定时间内的执行次数。简单点说就是通过防抖函数让某个触发事件在 n 秒内只会被执行一次。

节流

节流是指绑定事件后,通过动作触发事件,在这段时间内,如果动作又发生,忽略该动作,一直到事件执行完后才能重新触发。通俗的说就是控制高频执行的次数。

节流函数 的作用是在一个单位时间内最多只能触发一次函数执行,如果这个单位时间内多次触发函数,只能有一次生效。

适用场景

防抖应用场景

防止多次提交按钮,只执行最后提交的一次

比较典型的有搜索事件,用户在不断输入值时,用防抖来节约请求资源,只有最后一次回车才能返回结果。还有按钮点击事件,为了防止用户多次重复提交也会使用防抖函数。

防抖应用场景

节流适合大量事件按时间做平均分配触发。

比较典型的有监听滚动或 resize 事件,比如是否滑到底部自动加载更多,调整窗口大小。

手写节流防抖函数

防抖

function debounce(fn, delay) {
    let timer = null;
    clearTimeout(timer); // 下次调用时会清除上次的timer, 然后重新延迟
    timer = setTimeout(function(){
        fn();
    }, delay);
}

节流

function throttle(fn, wait) {
    let timer = null
    return function () {
        let context = this
        let args = arguments
        if (!timer) {
            timer = setTimeout(() => {
                timer = null
                fn.apply(context, args)
            }, wait)
        }
    }
}

总结

  • 防抖:防止抖动,规定时间内事件触发会被重置,避免事件被误伤触发多次。代码实现重在清零 clearTimeout。防抖可以比作等电梯,只要有一个人进来,就需要再等一会儿。业务场景有避免登录按钮多次点击的重复提交。
  • 节流:控制流量,单位时间内事件只能触发一次,与服务器端的限流 (Rate Limit) 类似。代码实现重在开锁关锁 timer=timeout; timer=null。节流可以比作过红绿灯,每等一个红灯时间就可以过一批。