应用场景:
当需要监听一个执行频率较高的事件(监听滚动条滚动,表单输入)时,执行函数触发的频率过高,但只需要函数最后一次执行结果,这时如果不对事件进行处理,过多的触发函数操作会降低浏览器的性能,降低用户的体验。这时候按照实际情况可以使用防抖和节流解决此问题
何为防抖:
防抖(debounce)是指在指定时间内多次触发函数,函数只会执行最后触发那一次,根据应用场景防抖可分为先不执行,指定时间之后再执行,立即执行,指定时间之后才可以再执行
先不执行,指定时间之后再执行:
function debounce(fun, delay) {
// 声明timer保存定时器的值,因为return函数内部有对timer的引用
// 所以(除了第一次)每次执行debounce函数timer都指向上一次定时器
let timer
return function() {
// 如果timer有引用,则清除timer引用的定时器
if(timer) clearTimeout(timer)
timer = setTimeout(() => {
// 调用需要进行防抖的函数,this一般为window
fun.apply(this)
}, delay)
}
}
立即执行,指定时间后才能再次执行
function debounce(fun, delay) {
let timer
return function() {
let current = !timer
if(timer) clearTimeout(timer)
timer = setTimeout(() => {
fun.call(this)
}, delay)
// 立即执行一次函数
if(current) fun.call(this)
}
}
何为节流
节流(throttle)简单来说,不受函数调用次数的影响,只在指定时间内执行,比如提交表单,节流时间为200ms,如果用户在200ms内多次点击提交,那么在200ms内函数只会执行一次,实现节流有两种方法,一种为定时器,第二就是使用时间戳
使用定时器
function throttle(fun, delay) {
let timer
return function() {
if(!timer) {
timer = setTimeout(() => {
fun.apply(this)
}, delay)
}
}
}
时间戳
function throttle(fun, delay) {
let prev = 0
let current = Date.now()
if(current - prev > delay) {
fun.call(this)
prev = current
}
}
欢迎各位大佬批评指正