节流和防抖的原理与解决办法

155 阅读2分钟

什么是节流

规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效

什么是防抖

在事件被触发n秒后再执行回调函数,如果在这n秒内又被触发,则重新计时。

节流与防抖的区别

节流与防抖的前提都是某个行为持续地触发,不同之处只要判断是要优化到减少它的执行次数还是只执行一次就行。

节流例子:像dom的拖拽,如果用消抖的话,就会出现卡顿的感觉,因为只在停止的时候执行了一次,这个时候就应该用节流,在一定时间内多次执行,会流畅很多。

防抖例子:像仿百度搜索,就应该用防抖,当我连续不断输入时,不会发送请求;当我一段时间内不输入了,才会发送一次请求;如果小于这段时间继续输入的话,时间会重新计算,也不会发送请求

如何实现节流防抖:

  • 1.可以调用插件Lodash 中文文档
  • 还有可以使用计时器来实现节流防抖等等…… ,具体请看以下代码

防抖代码实现:

<input name="username" type="text" oninput="checkUsername(this)">
<script>
    var handler;
    function checkUsername(it) {
        clearTimeout(handler);
        handler = setTimeout(() => {
            // TODO
        }, 1000)
    }
</script>

上面代码的意思是:如果在1000毫秒内,反复执行checkUsername函数,那么setTimeout就会被反复清除,并且反复设置一个新的1000毫秒的定时任务。直到你执行checkUsername的前后两次间隔超过1000毫秒,定时任务才有机会执行一次。

节流代码实现:

<input name="username" type="text" oninput="checkUsername(this)">
<script>
    var isRuning = false;
    function checkUsername(it) {
        if (!isRuning) {
            isRuning = true;
            // TODO
            setTimeout(() => isRuning = false, 1000)
        }
    }
</script>

这串代码的意思是:第一次执行checkUsername的时候,!isRuning为ture,执行关键代码,改变isRuning为true,设置一个1000毫秒后再把isRuning再改为false。那么,当你在1000毫秒内反复执行checkUsername的话,关键代码都不会执行,只有等到定时器执行后,再次执行checkUsername,才会执行关键代码。