likes
comments
collection
share

前端面试题 你还不会防抖节流嘛? 带你手撕防抖节流。

作者站长头像
站长
· 阅读数 5

学会防抖节流,这一篇文章就够了

哈喽哈喽,我是你们的金樽清酒。昨天我在面试的时候呀,面试官说有啥要问他的嘛,我想了一想,问咱们公司的项目有啥要性能优化的嘛,比如防抖节流啥的?引诱面试官上钩。面试官说,啊那你就说一下什么是防抖节流吧。那到你秀肌肉的时候啦,小小的防抖节流拿下。

什么是防抖!!!

什么是防抖呢?就是用户频繁的点击,猛戳屏幕,那你要触发几次呢,那肯定只能触发一次嘛,只有等用户不再猛戳屏幕,不再抖动的时候再执行操作,不然会重复的执行一个操作,极大的浪费性能。作为一个程序员来说,永远都不能相信客户怎么操作你的程序。所以我们就要做好防抖这个程序。

小demo展示

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <button id="btn">点击</button>
</body>
<script>
    let btn = document.getElementById('btn')
    btn.addEventListener('click', handle)
    function handle() {
        console.log('提交了')
    }
</script>

</html>

前端面试题  你还不会防抖节流嘛? 带你手撕防抖节流。 可以看到当用户点击的时候,用户一直向后端发送接口请求。假设一下这么一个场景,当网络不佳的时候,用户会一直发接口请求然后后端就会收到很多的接口请求,实际上这是可以避免的,我们只需要一次发送接口请求就行了。那我们就需要一个节流的高阶函数。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <button id="btn">点击</button>
</body>
<script>
    let btn = document.getElementById('btn')
    btn.addEventListener('click', debounce(handle, 1000))
    function handle(e) {
        console.log('提交了')
    }

    function debounce(fn, wait) {
        let timer = null
        return function (...args) {
            // 清除定时器
            clearTimeout(timer)
            timer = setTimeout(() => {
                fn.call(this, ...args)
            }, wait)
        }
    }
</script>

</html>

前端面试题  你还不会防抖节流嘛? 带你手撕防抖节流。 我们可以写一个debounce函数,里面return一个函数,因为addEventListene的第二个参数就是一个函数,里面写一个定时器,执行我们要执行的内容,然后给这个定时器一个名称,在外面清除定时器,由于闭包的存在,函数的调用栈里面有上一个定时器的内容,所以可以清除上一个定时器,这样就达到了防抖的效果,直到用户不在"手抖"后再执行这个函数。但是我们会改变了this的指向,所以要用.call将this指针再指向fn,也就是指向我们要执行的那个函数。这样一个防抖的效果就实现了。

什么是节流!!!

什么是节流,就是在一定的时间内只执行一次操作。就像游戏中的英雄有cd一样,不可能一直放技能。比如一个搜索框,不能用户才输入一个字母就,边输入就框框的发接口请求,这样也会导致后端突然收到大量的接口请求。所以我们要用节流来控制在某一段时间内该操作只执行一次。

那么,如何实现节流呢???

 function throttle(fn, wait) {//节流的方法
        let pre = Date.now()
        return function (...args) {
            let cur = Date.now()
            if (cur - pre > wait)
                fn.call(this, ...args)
            pre = cur//保存执行时的时间作为记录
        }
    }

我们无非就是想让函数在符合一个时间的条件下执行,那么我们可以用时间戳来完成。在函数调用的时候用一个时间戳来表示当前的时间。在返回的函数里面再记录一个时间戳,由于闭包的存在,外层的时间戳会被记录下来,于是只要里面的时间戳与外面的时间戳的差满足那个条件,那么我们的操作就执行一次,同时将执行时的时间戳记录下来,寻找下一个符合条件的时间。同时不要忘记this指针的指向问题。

好啦,防抖节流的分享到这里啦。希望有帮助到大家。如果有想一起学习,刷题,向大厂进发的可以加我的微信wxid_hs2b5ajazj4422。