乐趣区

JS中的函数防抖

JS 中的函数防抖

一、什么是函数防抖

概念:函数防抖(debounce),就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。

举个栗子,坐电梯的时候,如果电梯检测到有人进来(触发事件),就会多等待 10 秒,此时如果又有人进来(10 秒之内重复触发事件),那么电梯就会再多等待 10 秒。在上述例子中,电梯在检测到有人进入 10 秒钟之后,才会关闭电梯门开始运行,因此,“函数防抖”的关键在于,在 一个动作 发生 一定时间 之后,才执行 特定事件

二、为什么需要函数防抖

前端开发过程中,有一些事件,常见的例如,onresizescrollmousemove ,mousehover 等,会被频繁地触发,不做限制的话,有可能一秒之内执行几十次、几百次,如果在这些函数内部执行了其他函数,尤其是执行了操作 DOM 的函数(浏览器操作 DOM 是很耗费性能的),那不仅会造成计算机资源的浪费,还会降低程序运行速度,甚至造成浏览器卡死、崩溃。这种问题显然是致命的。

除此之外,重复的 ajax 调用不仅会造成数据关系的混乱,还会造成网络拥塞,增加服务器压力,显然这个问题也是需要解决的。

三、函数防抖如何解决上述问题

根据上面对问题的分析,细细思索,可以想到如下解决方案。

函数防抖的要点,也是需要一个 setTimeout 来辅助实现。延迟执行需要跑的代码。如果方法多次触发,则把上次记录的延迟执行代码用 clearTimeout 清掉,重新开始。如果计时完毕,没有方法进来访问触发,则执行代码。

四、函数防抖的代码实现

根据以上分析,我们对“函数防抖”进行代码实现,如下:

function debounce(fn,wait){
    var timer = null;
    return function(){if(timer !== null){clearTimeout(timer);
        }
        timer = setTimeout(fn,wait);
    }
}
    
function handle(){console.log(Math.random());
}
    
window.addEventListener("resize",debounce(handle,1000));

以上方法本人亲测有效,小伙伴们可放心食用(注意,函数触发方式为“resize”,改变窗口大小,观察浏览器控制台的变化)。

五、函数节流的使用场景

函数防抖一般用在什么情况之下呢?一般用在,连续的事件,只需触发一次回调的场景具体有:

  1. 搜索框搜索输入。只需用户最后一次输入完,再发送请求
  2. 手机号、邮箱验证输入检测
  3. 窗口大小 resize。只需窗口调整完成后,计算窗口大小,防止重复渲染。

目前遇到过的用处就是这些了,理解了思路,小伙伴可以把它运用在适当的场合,提高代码质量。

总结

函数防抖其实是分为“立即执行版”和“非立即执行版”的,根据字面意思就可以发现他们的差别,所谓立即执行版就是 触发事件后函数不会立即执行,而是在 n 秒后执行,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。 而“非立即执行版”指的是 触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的效果。

在开发过程中,我们需要根据不同的场景来决定我们需要使用哪一个版本的防抖函数,一般来讲上述的防抖函数都能满足大部分的场景需求。但我们也可以将非立即执行版和立即执行版的防抖函数结合起来,实现最终的双剑合璧版的防抖函数。

退出移动版