防抖和节流很长一段时间不太懂什么意思,总觉得它们是一个东西。但是花了时间着重了解以后发现它们还是有不少区别的。
但是有个共同点就是都是使用setTimeOut定时器实现的。
特点:一个函数,短时间多次触发,但是只执行最后一次触发的事件
思路:将所有的消息推入消息队列,但是只执行最后一次的消息
用处:如一个点击发送请求的按钮。为了防止用户由于误触导致的多次点击。所以只执行短时间内多次触发的最后一次触发。
核心代码:
以一个点击数字增加的例子说明
每次执行函数时都清除上一次的定时器。清除了这个定时器以后setTimeout内的代码(h_n.innerText = ++n)不再执行。
如果在一秒内再次触发了add函数,那么上一次触发的定时器将不再执行
事物队列解析:
add()方法中的定时器数字加1的操作属于消息队列中的内容,而消息会在调用栈清空的时候执行
如果在短时间(定时器的1S时间内)再次触发了add()方法,此时会先将上一个定时器清除(清除以后,上一个数字加1的操作将不再执行)
对应的Event Loop的过程就是:把上一个进入消息队列的消息删除,这次新的消息将进入消息队列
特点:持续触发情况下,只会在固定的时间间隔执行。比如百度的搜索显示下拉列表的功能
思路:只将肯定执行的消息推入消息队列
代码示例:
<script>
let n = 1
let cont = document.getElementById("cont")
cont.innerText = n
let swch = true // 节流的开关
function add(){
if(swch) {
swch = false
setTimeout(()=>{
swch = true
cont.innerText = ++n
},1000)
}
}
</script>
说明:
add()方法内,判断一下开关是否打开,如果打开说明上一个定时器回调已经执行完毕,可以执行下一次函数。如果关闭,表示1s时间还没到,开关还没有打开,此时无法执行 ++n操作
事件队列解析:
有一个全局的开关,add()方法根据这个开关决定是否将该消息推入消息队列