概念

函数防抖(debounce)

当调用动作过n毫秒后,才会执行该动作,若在这n毫秒内又调用此动作则将重新计算执行时间

函数节流(throttle)

预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新周期

函数节流(throttle)函数防抖(debounce)都是为了限制函数的执行频次,
以优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟,假死或卡顿的现象。

常用的场景有:

  • window对象的resize、scroll事件
  • 拖拽时的mousemove事件
  • 文字输入、自动完成的keyup事件

话句话来说这两者的区别就是,是否在动作持续的过程中,重新计算过期时间。

防抖 只会在动作“真正结束”后才触发函数,节流 会在超过预定时候后就会触发函数

源码

函数防抖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function debounce(fn, wait) {
var timer = null;
return function () {
var context = this
var args = arguments
if (timer) {
clearTimeout(timer);
timer = null;
}
timer = setTimeout(function () {
fn.apply(context, args)
}, wait)
}
}

var fn = function () {
console.log('boom')
}

setInterval(debounce(fn,500),1000) // 第一次在1500ms后触发,之后每1000ms触发一次

setInterval(debounce(fn,2000),1000) // 不会触发一次(我把函数防抖看出技能读条,如果读条没完成就用技能,便会失败而且重新读条)

函数节流:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function throttle(fn, gapTime) {
let _lastTime = null;

return function () {
let _nowTime = + new Date()
if (_nowTime - _lastTime > gapTime || !_lastTime) {
fn();
_lastTime = _nowTime
}
}
}

let fn = ()=>{
console.log('boom')
}

setInterval(throttle(fn,1000),10)

参考

  1. 函数节流与函数防抖
  2. 轻松理解JS函数节流和函数防抖