前言:
防抖和节流都是防止函数多次调用,在时间轴上控制函数的执行次数。
函数防抖(debounce)
在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时,先计算时间后执行。
生活中的实例:有人进入电梯,电梯则在10秒后自动关门,如果10秒内又有人进入电梯,则电梯重新计时,自动关门。
function debounce(fn, delayTime) {
let timer = null
return function (args) {
if (timer) {
timer = null
clearTimeout(timer)
}
let _this = this
let _args = args
timer = setTimeout(function () {
fn.call(_this, _args)
}, delayTime)
}
}
let inputDom = document.getElementById('input2')
inputDom.addEventListener('keyup', debounce((e) => {console.log(e.target.value)}, 1000))
防抖原理
为了减少频繁发生的事件的资源请求,防抖是通过在用户没有操作的情况下,如果在等待时间内用户没有操作,则执行回调,如果有操作,继续等待相应时间间隔。所以在闭包函数内,初始化一个时间参数timer,如果timer为空,则表示回调事件没执行或者已执行完毕,代表在等待时间内用户没有操作,相反,如果timer不为null,清空timer,重新计时。
函数节流(throttle)
n秒内回调函数只会被执行一次,先执行后计算。
setTimeout实现函数节流
function throttle(fn, wait) {
var timer = null
if (timer) return
return function() {
let _this = this
let args = arguments
timer = setTimeout(function() {
fn.apply(_this, args) timer = null
},
wait)
}
}
时间差实现函数节流
function throttle(fn, wait) {
var lastTime = 0
return function() {
let _this = this
let args = arguments
let nowTime = new Date()
if (nowTime - lastTime > wait) {
fn.apply(_this, args) lastTime = nowTime
}
}
}
节流原理
函数节流的目的是为了让函数在特定时间内疚执行一次,这也是setTimeout的设计初衷,所以可以直接用setTimeout实现,当然执行完回调一定要将timer置空。另外一种思路就是计算触发时间和执行时间的差值,大于再执行回调。
总结
函数防抖就是特定时间内触发动作的话,重新计时。函数节流是特定时间内触发动作只会有一次回调。
所以函数防抖适用的场景:监听窗口的滚动,缩放。高频发生的一些事件。
函数节流适用的场景:涉及与后端交互的按钮,由于网络原因或者其他原因,导致接口没有返回值,用户一直点点点的问题。
|
|