函数的防抖和节流,学前端也不少时间了,这两个词还是第一次遇到,给自己科普一波。
函数防抖debounce:指定时间间隔内只会执行一个任务。
举个例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <!DOCTYPE html> <html> <head> <title>demo</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <input @keyup="write" /> </div> </body> <script type="text/javascript"> new Vue({ el: "#app", data: {}, methods: { write: function() { console.log(123) } } }) </script> </html>
|
当我们在输入框中输入内容(即键盘触发一次keyup事件)都会打印一次123,如图
防抖就是要控制这个频率,比如用500ms
作为一次频率间隔
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
| <!DOCTYPE html> <html> <head> <title>demo</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <input @keyup="write" /> </div> </body> <script type="text/javascript"> new Vue({ el: "#app", data: { timeout: null }, methods: { write: function() { if(this.timeout) { clearTimeout(this.timeout) } this.timeout = setTimeout(()=>console.log(123),500) } }
</script> </html>
|
效果如下:
具体理解一下这段代码:
clearTimeout
是用来清除定时器的,上述代码中,当我们第一次触发keyup
事件的时候,timeout
(定时器返回的id)是null,所以不会对timeout
做清除操作,接下去第一次触发定时器操作,定时时间是500ms
,假设此时timeout
被赋值为1,如果在这个500ms
的时间内,再次触发keyup
操作时候,会清除timeout
,也就是说,第一个500ms
内触发的那次操作将被取消,以此类推,最终的触发时间按照第一个超过500ms
还没继续触发的操作为准。
函数节流
接下来看节流,话说这个词语很抽象,其实就是指连续触发事件但是在 一段时间内只执行一次函数。节流会稀释函数的执行频率,节流有两种实现方式,一种是利用时间戳,代码如下:
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
| <!DOCTYPE html> <html> <head> <title>demo</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <input @keyup="write" /> </div> </body> <script type="text/javascript"> new Vue({ el: "#app", data: { previous: 0 }, methods: { write: function() { var now = +new Date(); if((now - this.previous)>5000000) { console.log(123) this.previous = now } } } }) </script> </html>
|
上面的代码可以看出来,函数只能在_5000000ms_中执行一次
另外一种是还是使用定时器(😂乍一看和防抖没啥差别,所以还是需要理解其中的奥义)
代码如下:
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
| <!DOCTYPE html> <html> <head> <title>demo</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <input @keyup="write" /> </div> </body> <script type="text/javascript"> new Vue({ el: "#app", data: { timeout: null }, methods: { write: function() { if(!this.timeout) { this.timeout = setTimeout(()=>{ this.timeout = null; console.log(123); }, 1000) } } } }) </script> </html>
|
理解一下防抖的函数:
上面代码中,定时器值timeout
初始化值为空,如果定时器为空则通过setTimeout()
延时,并且timeout
赋值为当前触发定时器的返回id
,并在>=1000ms
之后将定时器再次置为空,才能触发下一次的操作。第一次触发keyup
事件的时候因为timeout = null
所以会触发定时器,假设触发之后timeout = 1
,然后在1000ms
内被再次触发了事件,此时因为timeout = 1
了,所以这个1000ms
内触发的事件都不会被操作,直到1000ms
之后,timeout
重新被赋值为null
,方可进行再一次的keyup
事件触发。
引用别人博客中的一段话
函数节流是指一定时间内js方法只跑一次。比如人的眨眼睛,就是一定时间内眨一次。这是函数节流最形象的解释。
函数防抖是指频繁触发的情况下,只有足够的空闲时间,才执行代码一次。比如生活中的坐公交,就是一定时间内,如果有人陆续刷卡上车,司机就不会开车。只有别人没刷卡了,司机才开车。
防抖一般应用于的场景:输入查询 当用户停止输入一段时间之后 就触发查询
节流一般像不停的点击触发,就可以用节流,稀释了操作的次数。
虽然自己整理以及操作了一遍,但是对这两个概念还只是自己的一些理解,若有偏差,望指正~