Codog

关注微信公众号:Codog代码狗

0%

节流(throttle)与防抖(debounce)

两个方法常见的使用场景:

  • 防抖:输入框搜索值,需要等待停止输入一段时间后再查询,比如停止输入200ms后触发查询操作
  • 节流:窗口resize,需要每间隔一段时间执行某个操作

简易版:

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
26
27
28
// 防抖
function debounce(func, delay) {
let timer;
return function() {
let context = this;
let args = arguments;
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args)
}, delay)
}
}

// 节流
function throttle(func, delay) {
let timer;
return function() {
let context = this;
let args = arguments;
if (timer) {
return;
}
timer = setTimeout(() => {
func.apply(this, args);
timer = null;
}, delay)
}
}
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// 防抖动 Debouncing把触发非常频繁的事件(比如按键,滚动)合并成一次执行
// 将会包装事件的 debounce 函数
function debounce(func, delay, immediate) {
var timer = null
return function () {
var context = this
var args = arguments
if (timer) clearTimeout(timer)
if (immediate) {
//根据距离上次触发操作的时间是否到达delay来决定是否要现在执行函数
var doNow = !timer
//每一次都重新设置timer,就是要保证每一次执行的至少delay秒后才可以执行
timer = setTimeout(function () {
timer = null
}, delay)
//立即执行
if (doNow) {
func.apply(context, args)
}
} else {
timer = setTimeout(function () {
func.apply(context, args)
}, delay)
}
}
}

// 节流函数允许一个函数在规定的时间内只执行一次。
var throttle = function (func, delay) {
var timer = null
var startTime = Date.now()

return function () {
var curTime = Date.now()
var remaining = delay - (curTime - startTime)
var context = this
var args = arguments

clearTimeout(timer)
if (remaining <= 0) {
func.apply(context, args)
startTime = Date.now()
} else {
timer = setTimeout(func, remaining)
}
}
}