JS的节流和防抖
为什么要有节流和防抖
在前端开发中有一部分的用户行为会频繁的触发事件执行,比如窗口的resize、scroll,提交表单等。而事件处理函数调用的频率无限制,很可能导致界面卡顿,甚至浏览器的崩溃。函数节流和函数防抖就是为了解决类似需求而生的
函数防抖
在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。也就是说,短时间内无论事件触发多少次,总是只会执行最后一次事件的回调方法
看一个例子
运行结果
先来说一下我的输入:1 》2 》3 》4 》5 》6 》7 》8 》9,输入9次,打印了9次,也就是说输入一次打印一次;
可以看到,我们只要按下键盘,就会触发这次ajax请求。不仅从资源上来说是很浪费的行为,而且实际应用中,用户也是输出完整的字符后,才会请求;
利用防抖
将请求函数 ajax 作为 setTimeout 的回调函数,设置 setTimeout 的时间为wait。需要一个变量 timeout 来保存当前所处的计时阶段,如果距离上次事件发生的 wait 时间段内再次发生该事件,那么把 timeout 清楚,即把上次的 setTimeout 事件清除,并重新计时;如果 wait 期间内没有再次触发相同事件,那么执行 fn 方法,即执行 ajax 方法。
运行结果
还是先说下我是怎么输入这9个数字的:先输入123,停了1秒多(打印出123),再次输入456,又停了一秒多(打印出123456),输入789(1秒后,打印出123456789);
当持续触发 keyup 事件时,ajax 请求函数只在keyup事件停止1000毫秒之后才会调用一次,也就是说,在持续触发keyup事件的过程中,请求函数ajax一直没有执行;
可以看到,我们加入了防抖以后,当你在频繁的输入时,并不会发送请求,只有你在指定时间间隔内没有输入时,才会执行函数。如果停止输入但是在指定时间间隔内又输入,会重新触发计时。
函数节流
引用1:当持续触发事件时,保证一定时间段内只调用一次事件处理函数。也就是说,预定一个函数只有在大于等于执行周期时才执行,周期内调用不执行;
引用2:规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效;
举个例子
当事件触发的时候,我们设置一个定时器,再次触发事件的时候,如果定时器存在,就不执行,直到 wait 时间后,定时器执行函数,并且清空定时器,这样就可以设置下个定时器;
当第一次触发事件时,不会立即执行函数,而是延迟 wait 秒后才执行。而后再怎么频繁触发事件,也都是每 wait 时间才执行一次。当最后一次停止触发后,由于定时器的 wait 的延迟,可能还会执行一次函数;
运行结果
我的输入:在1秒之内输入 123,但是只打印出了 1,说明在 1 秒内触发多次事件,只会执行一次。
适用场景
debounce(防抖)
1、search搜索联想,用户在不断输入值时,用防抖来节约请求资源
2、window触发 resize 的时候,不断地调整浏览器窗口大小会不断触发这个事件,用防抖来让其只触发一次
throttle(节流)
1、鼠标不断点击提交,一段时间内只让一次点击生效
2、监听滚动事件,比如是否滑到底部自动加载更多
参考博客:https://www.cnblogs.com/momo798/p/9177767.html