日常开发过程中,滚动事件做复杂计算频繁调用回调函数很可能会造成页面的卡顿,这时候我们更希望把多次计算合并成一次,只操作一个精确点,JS把这种方式称为debounce(防抖)和throttle(节流)
防抖
概念
: debounce。其概念其实是从机械开关和继电器的“去弹跳”(debounce)衍生 出来的,基本思路就是把多个信号合并为一个信号。
即: 将多次事件触发, 合并成一个。
实现
:通过定时间调用函数, 通过一个闭包接收定时器, 如果在定时器时间内再次调用改方法,则清空定时器,重新创建新的定时器。从而达到多次频繁点击时间只调用一次。
意义
: 减少不必须要的性能损耗
代码实现
:
function debounce(func, delay) {
let timeout
return function() {
clearTimeout(timeout) // 如果持续触发,那么就清除定时器,定时器的回调就不会执行。
timeout = setTimeout(() => {
func.apply(this, arguments)
}, delay)
}
}
节流
概念
: 节流的意思是让函数有节制地执行,而不是毫无节制的触发一次就执行一次。什么叫有节制呢?就是在一段时间内,只执行一次。
实现
:通过闭包变量,判断是否调用了定时器方法,如果调用则返回,没有则触发定时器,并改变变量
意义
: 减少不必须要的性能损耗,在n秒值时间只触发了一次
代码实现
:
function throttle(func, delay) {
let run = true
return function () {
if (!run) {
return // 如果开关关闭了,那就直接不执行下边的代码
}
run = false // 持续触发的话,run一直是false,就会停在上边的判断那里
setTimeout(() => {
func.apply(this, arguments)
run = true // 定时器到时间之后,会把开关打开,我们的函数就会被执行
}, delay)
}
}
节流与防抖的区别
节流的实现方法为: 一段时间内,时间只执行一次, 如果事件在这段时间内,再次被点击, 则直接返回,不调用定时器的方法
防抖的实现方法为: 一段时间内,事件再次调用,则重新创建定时器任务,多次点击,事件执行的事件会更久。