Fork me on GitHub

简单实现函数去抖与函数节流

输入框里的值需要事实提交到后台,为了避免频繁发送请求,给服务端压力,王二使用了函数去抖

一、问题

以下场景往往由于事件频繁被触发,因而频繁执行DOM操作、资源加载等重行为,导致UI停顿甚至浏览器崩溃。

  • window对象的 resizescroll事件

  • 拖拽时的 mousemove事件

  • 射击游戏中的 mousedownkeydown事件

  • 文字输入、自动完成的 keyup 事件

实际上对于 windowresize事件,实际需求大多为停止改变大小n毫秒后执行后续处理;而其他事件大多的需求是以一定的频率执行后续处理。针对这两种需求就出现了debouncethrottle 两种解决办法。

二、解决方法

在函数库 underscore 里有函数去抖的实现方法,但是王二认为没有必要因此引用一个库,于是结合网上资料写了一个简单的函数去抖与函数节流的实现,参考如下代码(可以直接运行):

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
<html>
<input id="a" type="text">
<input id="b" type="text">
</html>
<script>
/**
* 空闲控制 返回函数连续调用时,空闲时间必须大于或等于 delay,func 才会执行
* @param delay {number} 空闲时间,单位毫秒
* @param func {function} 请求关联函数,实际应用需要调用的函数
* @return {function} 返回客户调用函数
*/
function debounce (func, delay) {
var timer
return function (...args) {
timer && clearTimeout(timer)
timer = setTimeout(() => {
func.apply(this, args)
}, delay)
}
}

/**
* 频率控制 返回函数连续调用时,func 执行频率限定为 delay 毫秒一次
* @param delay {number} 延迟时间,单位毫秒
* @param func {function} 请求关联函数,实际应用需要调用的函数
* @return {function} 返回客户调用函数
*/
function throttle (func,delay) {
var last = 0
return function(...args){
var curr = +new Date()
if (curr - last > delay){
func.apply(this, args)
last = curr
}
}
}
document.getElementById("a").addEventListener("input",debounce(() => {
console.log("函数去抖")
}, 500))
document.getElementById("b").addEventListener("input",throttle(() => {
console.log("函数节流")
}, 500))
</script>

三、参考文章

“^_^肥仔John”的博客圆文章
“anetin”的segmentfault文章

-------------本文结束感谢您的阅读-------------