# 防抖 debounce
# 介绍
事件触发一段时间后才会调用,频繁触发只会在最后一次执行。一般使用在搜索联想
# 实现
/**
* @desc 函数防抖
* @param {Function} callback 回调函数
* @param {Number} wait 延迟毫秒数
* @param {Boolean} immediate 立即执行
*
* @return {Function}
*/
const debounce = (callback, wait = 300, immediate = false) => {
let timer
return function () {
let ctx = this
let args = arguments
if (timer) {
clearTimeout(timer)
}
if (immediate) {
let callNow = !timer
timer = setTimeout(() => {
timer = null
}, wait)
if (callNow) {
callback.apply(ctx, args)
}
} else {
timer = setTimeout(() => {
callback.apply(ctx, args)
}, wait)
}
}
}
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
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
# 节流 throttle
# 介绍
连续触发事件,但在一段时间内只触发一次。一般使用在resize、touchmove,无限加载等。
防止表单提交按钮被多次触发,我们应该选择使用节流而不是防抖方案,秒杀抢购等业务场景。
# 实现
/**
* @desc 函数节流 时间戳版本
* @param callback 函数
* @param wait 延迟执行毫秒数
*/
const throttle = (callback, wait) => {
let prev = Date.now()
return function () {
let context = this
let args = arguments
let now = Date.now()
if (now - prev >= wait) {
callback.apply(context, args)
prev = now
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* @desc 函数节流 定时器版本
* @param callback 函数
* @param wait 延迟执行毫秒数
*/
const throttle = (callback, wait) => {
let timer = null
return function () {
let context = this
let args = arguments
if (!timer) {
timer = setTimeout(() => {
callback.apply(context, args)
timer = null
}, wait)
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* @desc 函数节流 结合
* @param callback 函数
* @param wait 延迟执行毫秒数
*/
const throttle = (callback, wait) => {
let timer = null
let prev = Date.now()
return function () {
let curTime = Date.now()
let remaining = wait - (curTime - prev)
let context = this
let args = arguments
// 取消定时器,重新计算remaining
clearTimeout(timer)
if (remaining <= 0) {
// 第一次触发立即执行处理函数
callback.apply(context, args)
prev = Date.now()
} else {
// 没到时间,最后一次触发还能执行处理函数
timer = setTimeout(callback, remaining)
}
}
}
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25