什么是节流?怎么实现节流函数
我们举例一个简单的 demo ,假设我们在页面用到了滚轮事件
window.addEventListener("scroll",()=>console.log("1"))
当我们从页面滚动一次
轻轻的一滚动执行了 16 次打印,这个函数的默认执行频率太高了,但是实际上我们并不需要如果高频的执行,毕竟浏览器的性能是有限的。
逻辑:函数的节流就是通过一个闭包保存标记(timer),在函数的开头判断这个标记是否为 0,如果为 0 就继续执行函数,否则 timer 不为 0 就 return 掉。就是我们滚动一次时执行一次 throttle 这个函数,timer 就加一,然后 setTimeout 重置为 0 ,当页面再滚动的时候,每隔 500ms 才会去执行一次逻辑判断。
const getLog = () => console.log("滚动");
// 执行事件
window.addEventListener('scroll', throttle(getLog));
// 防抖函数
function throttle(fn, interval=500){
let timer = 0;
return function(...arg){
let _this = this;
if(timer)return;
fn.call(_this, ...arg);
timer = setTimeout(()=>{
timer = 0;
}, 500);
};
};
这时候的控制台打印信息如下:
什么是防抖?怎么实现防抖函数
很多时候防抖是用来处理用户输入框的,提醒用户用户名是否被注册了。
<body>
<input type="text" />
<script>
let inputEl = document.querySelector('input[type=text]');
const getLog = () => console.log("用户输入了");
inputEl.addEventListener('input', getLog);
</script>
</body>
我们来看控制台打印信息
其实不需要每次输入时都向后端发起请求来验证用户名是否被注册,只需要在用户输入完毕时发起请求来验证用户名是否被注册,否则每输入一个字符就发起一个请求,大大影响性能。
在第一次触发事件后,不应该立即执行函数,而是给出一个期限值比如 500ms 。
如果 500ms 内没有再次输入,那么就执行函数。
如果 500ms 内再次触发输入,那么当前的计时取消,重新开始计时。
效果:短时间内大量触发同一事件,只会执行最后一次
实现:既然前面都提到了计时了,那实现的关键就在于 setTimeOut 这个函数了。
let inputEl = document.querySelector('input[type=text]');
const getLog = () => console.log("用户输入结束,发起请求验证用户名是否被注册");
// 执行事件
inputEl.addEventListener('input', debounce(getLog))
// 防抖函数
function debounce(fn, interval=500){
let timer = 0;
return function(...arg){
let _this = this;
clearTimeout(timer);
timer = setTimeout(()=>{
fn.call(_this, ...arg);
},interval);
};
};
这时候我们再来看一下效果。
可以看出,当我们输入结束之后模拟向后端发起请求,这就完成了一个简单的防抖函数。