一、前言
本质上是优化高频率执行代码的一种手段
如:浏览器的
resize
、scroll
、keypress
、mousemove
等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能
为了优化体验,需要对这类事件进行调用次数的限制,对此我们就可以采用 防抖(debounce) 和 节流(throttle) 的方式来减少调用频率
二、节流函数的定义
限制一个函数在一定时间内只能执行一次
我自己的理解: 节流函数就是 在规定时间内 不管触发几次该事件,都只执行第一次,第一次触发事件等待delay后,事件执行。timer置为null,再次循环。
三、节流函数的实现
1.节流函数的时间戳写法
// 时间戳写法 function throttled1(fn, delay = 500) { let oldtime = Date.now(); return function (...args) { let newTime = Date.now(); if (newTime - oldtime >= delay) { fn.apply(null, args); oldtime = Date.now(); } }; }
2.节流函数的定时器写法
// 正常使用定时器写法 function throttled2(func, delay) { let timer; return function (...args) { if (!timer) { timer = setTimeout(() => { func.apply(this, args); timer = null; }, delay); } }; }
3.节流函数使用的具体案例
具体案例内容: 当点击确定按钮时,利用了节流函数,一定时间内只能打印输出一次,可以自己保存跑一下感受一下效果,实现了节流函数的效果。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <button id="button">确定</button> <script> function throttled(func, delay) { let timer; return function (...args) { // 这里要判断定时器是否存在,如果存在,就不执行, 如果不存在为null,说明上一次执行完毕,定时器已经为空,可以再次执行下面的函数。 if (!timer) { timer = setTimeout(() => { func.apply(this, args); timer = null; }, delay); } }; } function submit() { // 输出随机函数 console.log(Math.random()); } let button = document.querySelector('#button'); button.addEventListener('click', throttled(submit, 1500)); </script> </body> </html>
四、防抖和节流区别
相同点:
都可以通过使用 setTimeout 实现
目的都是,降低回调执行频率。节省计算资源
不同点:
函数防抖,在一段连续操作结束后,处理回调,利用clearTimeout和 setTimeout实现。函数节流,在一段连续操作中,每一段时间只执行一次,频率较高的事件中使用来提高性能
函数防抖关注一定时间连续触发的事件,只在最后执行一次,而函数节流一段时间内只执行一次
例如,都设置时间频率为500ms,在2秒时间内,频繁触发函数,节流,每隔 500ms 就执行一次。防抖,则不管调动多少次方法,在2s后,只会执行一次。
五、节流函数的应用
滚动加载,加载更多或滚到底部监听
搜索框,搜索联想功能