1. 函数节流是什么?
函数节流指的是限制一个函数在一定时间内只能执行一次;应用于一些很容易被多次触发的事件,比如oninput输入事件和window.onscroll窗口滚动事件,如果不限制,这些事件有可能一秒之内执行几十次、几百次,如果在这些函数内部执行了其他函数,比如执行了操作 DOM 的函数(浏览器操作 DOM 是很耗费性能的)或者是axios访问等,那不仅会造成计算机资源的浪费和服务器压力,还会降低程序运行速度,甚至造成浏览器卡死、崩溃;这种问题显然是致命的。
2. 函数节流的原理
主要就是对于事件间隔的控制,因此主要有两种方案;一种方案就是设置定时器,也可以理解成为一个开关,先将开关打开,开始执行目标函数前立刻关闭,在目标函数内部设置在完成后打开开关,因此目标函数没有执行完,内部打开开关前都无法再次进入这个函数;另一种方案就是使用时间戳,记录一个当前时间,再次执行的时候获取事件和此前记录的时间作差取间隔,间隔时间大于一定值时才能运行。
3. 函数节流的代码实现
3.1 使用定时器/开关
button.onclick = (function (){
//默认开关打开
let flag = true;
if(flag){
//先关上开关
flag = false;
funciton say(){
//执行hi里面的内容
console.log("等我完事儿,再打开开关");
//内容执行完成,再打开开关
flag = true;
}
}
})();
打印的话,可能运行的很快没什么感觉,用延时器来看一下
button.onclick = (function (){
//默认开关打开
let flag = true;
if(flag){
//先关上开关
flag = false;
//执行函数
console.log("等我完事儿,再打开开关");
//设置延时器,两秒后打开开关
setTimeout(function(){
flag = true;
},2000)
}
})();
第一次执行进入函数体,执行目标函数,设置一个延时器;在延时器执行前,开关处于关闭状态,无法再次触发
3.2 使用时间戳
window.onscroll = (function(){
//初始设定为0
var lasttime = 0;
return function(){
//每次触发事件获取当前时间
var now = new Date().getTime();
//若时间间隔大于了200ms,才执行函数体
if( now-lasttime > 200 ){
//重新赋值时间
lasttime = now;
//要执行的目标代码
fn();
}
}
})()
如果时间间隔不大于200ms,则不会进入函数体,控制了执行的频率,最快200ms才能执行一次
4. 函数防抖的原理
主要是使用定时器,通过设定延时器和短时间内运行清除定时器重新开启的方式,让定时器内的函数不会反复触发,在延时器设定后且规定时间内没有被清除的情况下,延时器成功延迟,内部函数执行。一个实际应用的例子就是搜索引擎输入框访问后台,根据当前输入的文字进行提示,但是oninput只要在输入就会一直触发,其实用户要查的是抖音热门bgm是啥,结果输入抖音就开始访问,造成了资源浪费。通过函数防抖可以实现在用户停止输入一段时间后才会触犯去访问后台。
5. 函数防抖的代码实现
//inputEle指的是页面的一个input
inputEle.addEventListener("keyup", (function(e){ //自运行函数
var t = null;
return function(){
clearTimeout(t); //每次触发,都把前面的定时器关闭,但第一次定时器并不存在
t = setTimeout(function(){ //开启新的定时器
//ajax(...); 发送请求到服务器
}, 300);
}
})() )
通过上述代码我们看出子运行函数每次键盘抬起都会触发,但是设定了延时器,并不是去运行ajax访问;如果用户在300ms以后再次输入出发了键盘抬起的事件,则会进入return里,先清除还没完成的t定时器,然后重新开启他,相当于延迟的时间刷新,虽然还没走完300ms,但是重新设定,又开始从300ms开始走;因此只要用户没有停止输入,键盘抬起后300ms没有操作才会执行里面的ajax请求,不会让ajax跟随用户的输入速度连续请求数据。
结尾:仅根据个人学习后的理解整理如上知识点,如有错误,请不吝赐教~