什么是防抖/节流
- 防抖(debounce):触发高频事件后 n 秒内函数只会执行一次,如果 n 秒内高频事件再次被触发,则重新计算时间;我们日常使用的百度搜索框就使用了防抖机制,只有在输入框不再输入内容一段时间之后才会弹出关键词索引
- 节流(thorttle):高频事件触发,但在 n 秒内只会执行一次;例如滑动到底部自动加载下一页,就可以通过节流来控制
区别:防抖只会在最终执行一次;而节流是每隔一段时间执行一次,起到稀释操作的作用
这里借用一张网络上的图片,前半部分节流,只会在某一时间点触发,可以看见a、b、c三个点在时间线上都是一样的;后半部分是防抖,a事件过了一段时间之后触发,b、c事件之间的间隔没有达到阈值,c事件就会覆盖b事件,最终只有c事件执行
为什么要防抖/节流
事件无法控制触发频率,会不断执行事件造成性能的浪费,比如鼠标位置、页面滚动……等,使用了防抖或节流就可以有效的控制不可控事件的触发,可以优化用户体验,甚至可以缓解服务器压力
怎样实现防抖/节流
防抖
通过不断地重置计时器timer来实现最终只执行一次
/**
* @description: 函数防抖,利用闭包返回防抖函数
* @param {*} fun 需要防抖的函数
* @param {*} wait 等待时间,默认0.5秒
* @return {*} 实际到用的防抖函数
*/
function debounce(fun, wait = 500) {
let timer = null
return function (...args) {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fun.apply(this, args)
}, wait)
}
}
节流
通过setTimeout执行事件来调控状态位
/**
* @description: 函数节流
* @param {*} fun 需要节流的函数
* @param {*} wait 等待时间,默认0.5秒
* @return {*}
*/
function throttle(fun, wait = 500) {
let valid = true
return function (...args) {
if (!valid) {
return false
}
// 工作时间,执行函数并且在间隔期内把状态位设为无效
valid = false
setTimeout(() => {
fun.apply(this, args)
valid = true
}, wait)
}
}