防抖与节流

7 阅读2分钟

使用场景

首先我们要了解为什么需要用到防抖,防抖也就是手抖。一旦我们点击提交按钮,这个结果就会提交到后端 ,但如果上亿人同时点击,那服务器不就炸了吗,所以我们需要限制一下。

限制用户点击

我们设置当用户点击了提交按钮之后就不可以再次提交了

<body>
    <button id="btn">提交按钮</button>
</body>
</html>
<script>
    function send(){
        console.log('发送请求');
        const btn = document.getElementById('btn');
        btn.disabled = true;
    }
    const btn = document.getElementById('btn');
    btn.addEventListener('click', send);
</script>

如果第一次请求失败,按钮会被永久禁用,导致用户无法重新提交。这是不合理的。

防抖

设置函数在用户操作一段时间后执行

<script>
    function send(){
        console.log('发送请求');  
    }
    const btn = document.getElementById('btn');
    btn.addEventListener('click', debounce(send,1000))
    function debounce(fn,wait){
        return function(){
           setTimeout(()=>{
            fn()
           },wait)
        }
    }
</script>

这样的话,请求会在1s之后发送。 但是这有一个问题啊,我点击了很多次,最终都会执行,只不过是在1s之后执行的,这没有实现我们的目的,所以我们要继续设置。

function debounce(fn, wait) {
        var timer = null;
        return function() {
            if (timer) {
                clearTimeout(timer);
            }
            timer = setTimeout(() => {
                fn();
            }, wait);
        };
    }

通过设置事件,如果time不为null说明之前设置过了定时器,clearTimeout销毁定时器,避免重复执行。等到时间到了,使用 setTimeout设置一个新的定时器,在 wait 毫秒后执行 fn函数,并将定时器 ID 赋值给 timer。 这样就可以实现,如果用户一直点击,就一直不会执行,等到用户点击的1s后没有再次点击那么,才会执行操作。

节流

节流是指在一定时间内,函数只能执行一次。比如,你可以设置一个按钮在 1 秒内最多只能点击一次,无论用户在这段时间内点击了多少次。这对于限制频繁触发的事件(如滚动、窗口调整大小或高频点击)非常有用。

function throttle(fn,wait){
            let oldTime = 0
                return function(){
                    let newTime=Date.now()
                    if(newTime-oldTime>wait){
                        fn()
                        oldTime=newTime
                    }
                }
        }

通过设置if(newTime-oldTime>wait),规定只有点击后的时间超过wait,这个请求才会执行

节流与防抖的区别

防抖:在连续触发结束后等待一段时间才执行。 常用于输入框搜索、窗口resize、提交按钮

节流:在固定时间间隔内最多执行一次。 常用于滚动事件、鼠标移动、游戏按键