防抖(debounce)
在一定时间内触发同一事件,函数只会在最后一次点击后执行。
可以理解为游戏中的“回城技能”,按了之后需要等待一段时间才能实现回城,中途任意一次重按都需要重新等待。
// func是用户传入需要防抖的函数
// wait是等待时间
function debounce(fn, wait) {
let timer = null //借助闭包
return function(...args) {
// 进入该分支语句,说明当前正在一个计时过程中,并且又触发了相同事件。
// 所以要取消当前的计时,重新开始计时
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, args)
}, wait) // 进入该分支说明当前并没有在计时,那么就开始一个计时
}
}
节流(throttle)
在一定时间内触发同一事件,函数立即执行一次后,该函数在指定的时间期限内不再工作,直至过了这段时间才能重新生效。
可以理解为游戏中的“普通技能”,在按了之后马上触发,但技能触发之后任你如何按键都无效,需要在等一定的冷却时间之后才能再次触发。
// func是用户传入需要节流的函数
// wait是等待时间
function throttle(fn, wait) {
// 上一次执行该函数的时间
let lastTime = 0
return function(...args) {
// 当前时间
let now = +new Date()
// 将当前时间和上一次执行函数时间对比
// 如果差值大于设置的等待时间就执行函数
if (now - lastTime > wait) {
lastTime = now
fn.apply(this, args)
}
}
}
使用案例(example):
贴上一个案例,立马体验一下防抖和节流的效果吧。
<body>
<button id="btn1">防抖点击</button>
<button id="btn2">节流点击</button>
<script>
function debounce(fn, wait) {
let timer = null
return function (...args) {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, args)
}, wait)
}
}
function throttle(fn, wait) {
let lastTime = 0
return function (...args) {
let now = +new Date()
if (now - lastTime > wait) {
lastTime = now
fn.apply(this, args)
}
}
}
function say() {
console.log('-------hello-------')
}
document.getElementById('btn1').onclick = debounce(say, 2000)
document.getElementById('btn2').onclick = throttle(say, 2000)
</script>
</body>