函数节流的目的
从字面上就可以理解,函数节流就是用来节流函数从而一定程度上优化性能的。例如,DOM 操作比起非DOM 交互需要更多的内存和CPU 时间。连续尝试进行过多的DOM 相关操作可能会导致浏览器挂起,有时候甚至会崩溃。尤其在IE 中使用onresize 事件处理程序的时候容易发生,当调整浏览器大小的时候,该事件会连续触发。在onresize 事件处理程序内部如果尝试进行DOM 操作,其高频率的更改可能会让浏览器崩溃。又例如,我们常见的一个搜索的功能,我们一般是绑定keyup事件,每按下一次键盘就搜索一次。但是我们的目的主要是每输入一些内容搜索一次而已。为了解决这些问题,就可以使用定时器对函数进行节流。
函数节流的原理
某些代码不可以在没有间断的情况连续重复执行。第一次调用函数,创建一个定时器,在指定的时间间隔之后运行代码。当第二次调用该函数时,它会清除前一次的定时器并设置另一个。如果前一个定时器已经执行过了,这个操作就没有任何意义。然而,如果前一个定时器尚未执行,其实就是将其替换为一个新的定时器。目的是只有在执行函数的请求停止了一段时间之后才执行。
简单的搜索demo
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <title>函数节流</title> </head> <body> <input id="search" type="text" name="search"> <script> var searchResult = (text) => { console.log("搜索:" + text); } var val = ''; const input = document.getElementById("search"); input.addEventListener("keyup", function(event){ let value = this.value.replace(/(\s*$)/g, "");//去除最后的空格 if(val !== value || val === ''){//和上次记录的搜索内容比较,内容一致则不搜索,第一次默认进入 throttle(searchResult, null, 500, this.value, 1000); } }); function throttle(Fun, context, layTime, text, allTime){ clearTimeout(Fun.timer); Fun._cur = Date.now(); //记录当前时间 if(!Fun._start){ //若该函数是第一次调用,则直接设置_start,即开始时间,为_cur,即此刻的时间 Fun._start = Fun._cur; } if(Fun._cur - Fun._start > allTime){ //当前时间与上一次函数被执行的时间作差,与allTime比较,若大于,则必须执行一次函数,若小于,则重新设置计时器 Fun.call(context, text); Fun._start = Fun._cur; val = text; }else{ Fun.timer = setTimeout(()=>{ Fun.call(context, text); val = text; },layTime); } } </script> </body> </html>
运行结果:
好吧,就到这了,如果有错误的地方,希望大家及时指正