如何给🥬🐕前端讲解防抖与节流

143 阅读2分钟

如何给🥬🐕前端讲解防抖与节流?

什么是防抖

用户停止操作后一段时间后触发方法

假如有一个输入框,需要在输入时对输入框内容验证,应在用户在输入完时自动验证,用户在输入中未输入完的时候不会触发验证,这时就可以用到防抖

也就是当用户停止输入300ms后进行验证,如果300ms内输入就重新计时

什么是节流

用户操作后,一段时间内继续操作将不会触发方法

一个登录页面,当用户点击了登录的时候,可能由于网络问题,未能及时响应,用户就会以为是点击无效,会再连续多次点击登录按钮,如果不做限制,就会发送很多次请求,这时就可以用到节流来限制

也就是当点击了第一次的时候执行登陆方法,如果在第一次点击的300ms内继续点击,将不会触发方法

实现一个防抖函数

对于防抖函数,可以使用定时器来实现

<html lang="en">
<head></head>
<body>
    <button onclick="handleClick()">click</button>
    <script>
        let timeout = null;
        function debounce(fn) {
            clearTimeout(timeout)
            timeout = setTimeout(fn, 300)
        }
         function log() {
            console.log('click')
        }
        function handleClick() {
            debounce(log)
        }
    </script>
</body>
</html>

防抖函数接受一个参数,为需要的操作回调,连续点击按钮的时候,只会执行最后一次操作

以上方法使用了全局变量来存储定时器,会造成全局污染,而且对开发中代码的阅读不够友好,可使用以下方法优化

<html lang="en">
<head></head>
<body>
    <button onclick="handleClick()">click</button>
    <script>
       function debounce(fn) {
            let timeout = null;
            return function () {
                clearTimeout(timeout)
                timeout = setTimeout(fn, 300)
            }
        }
        function log() {
            console.log('click')
        }
        let handleClick = debounce(log)
    </script>
</body>
</html>

将存储定时器的变量timeout定义在内部并返回一个方法暴露,让全局都可以使用到函数内的变量timeout

假如操作方法需要传入参数,就需要以下代码实现

<html lang="en">
<head></head>
<body>
    <button onclick="handleClick(1,2,3)">click</button>
    <script>
        function debounce(fn) {
            let timeout = null;
            return function () {
                clearTimeout(timeout)
                timeout = setTimeout(() => {
                    fn(...arguments)
                }, 300)
            }
        }
        function log(a, b, c) {
            console.log(a, b, c)
        }
        let handleClick = debounce(log)
    </script>
</body>
</html>

将arguments通过三点运算符传入实际操作的方法中,也可以使用apply传参

以上就是防抖函数的实现,节流函数通过相同的原理封装即可

以下是前端🥬🐕实现的节流函数

<button onclick="throttle(4,5,6)">节流</button>
function throttleClick(fn, time) {
    let isClick = true
    function b() {
        if (!isClick) return
        fn(...arguments)
        isClick = false
        setTimeout(() => {
            isClick = true
        }, time);
    }
    return b
};
function throttleConsole(a, b, c) {
    console.log(a, b, c)
}
let jieliu = throttleClick(throttleConsole, 1000)