防抖与节流一直是一个老生常谈的问题,主要运用于避免多从短时间内多次触发事件而造成的资源浪费
但总是将两个概念混淆每每忘记所以决定写下来

防抖(debounce)

个人理解:

防抖可以简单的从生活中理解来看,就像大家平时追剧没开VIP被迫强制看广告,每每当广告到最后几秒的时候结果手一抖划出去了再次点开,恭喜恭喜再次喜得30s广告,直到某一次手不贱了忍着看完了广告,正片才开始了

总得来说就是在一段时间内也就是上述的广告时间未结束前,你手贱了,那你的看广告记录清零,只有下次你忍着看完广告,然后才播放正片

核心:断定时器是否存在,若存在则废弃上一个定时器,开启新的定时器

代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
function debounce(fn, timeout) {
let timer = null;
return function (...args) {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
// setTimeout的回调函数中的this值通常默认为全局对象或undefined(在严格模式下)。
// 这意味着如果你希望回调函数中的this保持与外部函数相同的上下文,你需要显式地设置它。
fn.apply(this, args)
}, timeout)
}
}

适用:

表单搜索

按钮点击

节流(throttle)

个人理解:

节流其实更好理解,就像每月月初你管家里面要生活费,然后一会你就收到支付宝到账XXXX元的信息,但当你还没到月底就花完了钱再去要生活费的时候,你就会收到“???没有,滚犊子,这个月已经给过你了”,你的请求响应为空

核心:在一定时间内只触发一次也就是最开始的请求

代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
function throttled(fn, delay) {
let timer = null
return function (...args) {
if (!timer) {
timer = setTimeout(() => {
// setTimeout的回调函数中的this值通常默认为全局对象或undefined(在严格模式下)。
// 这意味着如果你希望回调函数中的this保持与外部函数相同的上下文,你需要显式地设置它。
fn.apply(this, args)
timer = null
}, delay);
}
}
}

适用:

鼠标移动

滚动加载

总结:

  • 函数防抖,在一段连续操作结束后,处理回调,也就是说连续多次触发只执行最后一次
  • 函数节流,在一段时间内只执行第一次操作,这段时间内的其他操作不予相应