JS 节流和防抖函数

节流函数

释义:控制会频繁触发的事件,减少其触发的频率,减轻对应事件的开销。
场景:容器的scroll事件、鼠标的mousemove事件

demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/** 实现思路:
** 参数需要一个执行的频率,和一个对应的处理函数,
** 内部需要一个lastTime 变量记录上一次执行的时间
**/
function throttle (func, wait) {
let lastTime = null
    // 为了避免每次调用lastTime都被清空,利用js的闭包返回一个function确保不生命全局变量也可以
return function () {
let now = new Date()
// 如果上次执行的时间和这次触发的时间大于一个执行周期,则执行
if (now - lastTime - wait > 0) {
func()
lastTime = now
}
}
}

// 调用
let throttleRun = throttle(() => {
console.log(123)
}, 400)
window.addEventListener('scroll', throttleRun)

这样就可以实现每400ms才打印一次123,减少scroll事件触发的频次。

防抖函数

释义:指对于在事件被触发n秒后再执行的回调,如果在这n秒内又重新被触发,则重新开始计时。
场景:输入验证、搜索栏实时搜索、多次提交拦截
demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function debounce (func, wait) {
let lastTime = null
let timeout
return function () {
let context = this
let now = new Date()
// (当前时间 - 上一次触发的时间 - 等待时间)判断是否可以触发新一次的时间
if (now - lastTime - wait > 0) {
setTimeout(() => {
func.apply(context, arguments)
}, wait)
} else {
// 在等待期间触发,则清空上一次的异步事件,重新开始计时
if (timeout) {
clearTimeout(timeout)
timeout = null
}
timeout = setTimeout(() => {
func.apply(context, arguments)
}, wait)
}
// 保存本次事件触发的时间
lastTime = now
}
}

参考

JS 函数节流和去抖
JavaScript 函数防抖(debounce)的实现


评论区