问题由来:html
在项目应用PeoplePicker控件的时候忽然联想到一个问题,在输入人名时不停的向后台发请求,取到数据库里面的数据。咱们都知道频繁的通讯会致使页面效率下降。可不能够设置个间隔,每次这个间隔通讯一次而不是每次输入一个字符就通讯一次呢。其实这里还有不少场景,好比resize事件,scroll事件。都会让一个回调函数不停的执行。页面操做成本是很是高的,若是不停的执行页面效率会打打折损。因而产生了两种解决方案:函数节流、函数去抖。数据库
函数节流:闭包
频繁的调用一个函数,咱们能够添加一些限制,能够缓解频繁调用,咱们能够设置个时间间隔,每次到时间调用一次。app
代码:dom
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> </head> <body> <input id="search" type="text" name="search"> <script> function queryData(text) { console.log(text); } var input = document.getElementById("search"); var handler = throttle(queryData, 1000); input.addEventListener("keyup", function (event) { handler(this.value); }); function throttle(fn, delay) { var self = this, lastTime = 0, timer; return function (value) { var now = new Date().getTime(); if (now - lastTime <= delay) { return; } lastTime = now; clearTimeout(timer); timer = setTimeout(function () { timeout = null; fn.apply(self, [value]); }, delay) } } </script> </body> </html>
思路:利用闭包函数throttle保存timer以及lastTime,若是两次的调用时间间隔小于设置的规定时间,就不去调用目标函数,若是大于这个时间间隔,就去设置一个timer,而后执行这个函数。这样作的目的能够达到频繁调用函数,可是须要在一段时间才回去执行该函数,这种方式就叫作函数节流。函数
效果:优化
一直不停的输入,没1秒会打一次log。this
函数去抖:spa
去抖能够理解成为是节流的一种状况,在一个条件内函数一直不执行,直到调出该条件。code
代码:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> </head> <body> <input id="search" type="text" name="search"> <script> function queryData(text) { console.log(text); } var input = document.getElementById("search"); var handler = debounce(queryData, 5000); input.addEventListener("keyup", function (event) { handler(this.value); }); function debounce(fn, delay) { var timer, self = this; return function (value) { clearTimeout(timer); timer = setTimeout(function () { timer = null; fn.apply(self, [value]); }, delay); }; } </script> </body> </html>
思路:函数调用n秒后才会执行,若是函数在n秒内被调用的话,则函数不执行,从新计算执行时间。
效果:
不停的输入不会打出log,中止输入打出log。
总结:函数节流在必定程度上能够优化页面效率,减小不必的dom渲染以及http请求,更重要的是对js能够有一个更深刻的理解。