一.本质
本质上二者都是优化高频率执行代码的一种手段。
一句话概括:防抖是碰到新调用就重置计时器;节流则是碰到新调用就无视。
比如:浏览器的resize、mouseover 等事件在触发时,会不断的调用绑定在事件上的回调函数,浪费资源,降低性能。所以,为了优化体验,需要对这类事件进行调用次数的限制,对此我们就可以使用防抖和节流的方式来减少调用频率。
二.定义
1.防抖:N秒后再执行该事件,若在N秒内被重复触发,则重新计时。即当持续触发事件时,一定时间段内没有再触发该事件,则事件处理函数才会执行一次,如果设定的时间到来之前,再次触发了时间,就重新开始延时。
1.1.为什么要防抖:有的操作是高频触发的,但是其实触发一次就可以了,比如监听输入框的输入,不需要用户每次输入一个字符就去触发监听,应该是用户完成一段输入后再去触发监听事件;再比如如果短时间内多次缩放页面,我们也不应该每次都去触发操作,只触发一次就可以了。也就是等用户高频事件完了,再进行事件的操作。
1.2.防抖怎么做:使用settimeout实现。触发事件,如果当前没有定时器,设定定时器。如果有定时器,重设定时器。
function debounce(func,wait){
let timeout=null;
return function(){
clearTimeout(timeout);
timeout=setTimeout(()=>{
func()
},wait)
}
}
防抖如果要立即执行,可加入第三个参数用于判断,实现代码如下:
function(func,wait,immediate){
let timeout=null;
return function(){
if(timeout){
clearTime(timeout)
}
if(immediate){
let isCallNow=!timeout;
timeout=setTimeout(function(){
timeout=null;
},wait)
if(isCallNow){
func()
}
}else{
timeout=setTimeout(function(){
func()
},wait)
}
}
}
2.节流:N秒内只执行一次,如果再N秒内被重复触发,只有一次生效。即高频率触发的事件,在指定的单位时间内,只相应一次。
2.1.为什么要节流:防抖存在一个问题,事件会一直等到用户完成操作后一段时间再触发,如果一直操作,则不会触发。节流就是减少流量,将频繁触发的事件减少,并且每隔一段事件执行,也就是控制事件触发的频率。
也就是某一个操作希望上一次的完成后再进行下一次,或者希望隔一段事件触发一次。
2.2.节流怎么做:思路:我们可以设计一种类似开关一样的函数,即事件触发时让函数执行一次,然后关闭这个开关。过段时间再将这个开关打开,再次触发事件。
完成节流可以使用时间戳与定时器的写法:使用时间戳的写法,事件会立即执行,停止触发后没有办法再次执行,代码如下:
function throttle(func,delay=1000){
let oldTime = Date.now()
return function(){
let newTime = Date.now();
if(newTime-oldTime >= delay){
func();
oldTime = Date.now()
}
}
}
使用定时器的写法,delay毫秒后第一次执行,第二次事件停止触发后依然会再一次执行。
function throttle(func,delay=1000){
let timer = null;
return function(){
if(!timer){
timer = setTimeout(() => {
func();
timer = null;
},delay);
}
}
}
将时间戳与定时器搭配使用,可以实现更精确的节流。
function throttle(func,delay){
let timer = null;
let starttime = Date.now();
return function(){
let curtime = Date.now();
let remaining = delay - (curtime - starttime) //从上一次到现在剩下的时间
clearTimeout(timer)
if(remaining <= 0){
func()
starttime = Date.now()
} else {
timer = setTimeout(fn,remaining);
}
}
}
三.区别
相同点:1.都可以通过setTimeout实现
2.米的都是降低执行频率,节省资源
不同点:
- 函数防抖,在一段连续操作结束后,处理回调,利用clearTimeout和 setTimeout实现。函数节流,在一段连续操作中,每一段时间只执行一次,频率较高的事件中使用来提高性能
- 函数防抖关注一定时间连续触发的事件,只在最后执行一次,而函数节流一段时间内只执行一次
例如,都设置时间频率为1000ms,在4秒时间内,频繁触发函数,节流,每隔 1000ms 就执行一次。防抖,则不管调动多少次方法,在4s后,只会执行一次。
四.应用场景
1.防抖在连续的事件中,只需触发一次回调的场景:
1.1.搜索框搜索输入,只需用户最后一次输入完,再向后台发送请求
1.2.窗口大小缩放,只需窗口调整结束,计算窗口大小,从而防止重复渲染
2.节流在间隔一段时间 执行一次回调的场景:
2.1.滚动加载,加载更多
2.2搜索框的搜索联想功能
标签:function,触发,防抖,节流,之防抖,js,事件,func From: https://blog.51cto.com/u_15402941/6064467