
防抖(debounce)
所谓防抖,就是指触发事件后 n 秒后才执行函数,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
防抖类型分为
- 非立即执行版
- 立即执行版
- 合成版本 防抖
防抖应用场景
- 登录、发短信等按钮避免用户点击太快,以致于发送了多次请求
- 调整浏览器窗口大小时,resize 次数过于频繁,造成计算过多,此时需要一次到位
- 文本编辑器实时保存,当无任何更改操作一秒后进行保存
非立即执行版
非立即执行版的意思是触发事件后函数不会立即执行,而是在 n 秒后执行,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
1/** 2 * @description: 3 * @param {*} func 触发的事件 4 * @param {*} wait 多少时长才执行事件 5 * @return {*} 6 */ 7 function debounce(func, wait) { 8 let timeout; 9 return function(){ 10 // 获取当前作用域和参数 11 const context = this; 12 const args = [...arguments] 13 // 如果当前timeout 存在 14 // 清空定时器,再次等待wait时间过后再次执行事件 15 if(timeout) clearTimeout(timeout) 16 // 定时执行 传递进来的事件 17 timeout = setTimeout(()=>{ 18 func.apply(context,args) 19 },wait) 20 } 21 }
立即执行版本
立即执行版的意思是触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的效果。
1function debounce(func,wait) { 2 let timeout; 3 return function () { 4 const context = this; 5 const args = [...arguments]; 6 if (timeout) clearTimeout(timeout); 7 const callNow = !timeout; 8 timeout = setTimeout(() => { 9 timeout = null; 10 }, wait) 11 if (callNow) func.apply(context, args) 12 } 13} 14
代码解析
当 执行
debounce函数时, 第一次进来时,timeout为false,所以callNow的值 为true,那么它会立即执行func函数,这时timeout的值 为true, 当timeout 值为true 时, 会执行 清空定时器,此时 timeout 又为 false 了, 这时callNow又 为true,再次执行func函数。一直循环这样的操作:
当
timeout为false时,会立刻执行func函数。当
timeout为true时,它会执行clearTimeOut,这时timeout又为false, 而callNow=! timeout, 就会立刻执行func函数了。
合成版本 防抖
通过传递
Boolean来决定执行哪种版本。
true为立即执行版false为非立即执行版本
debounce(func,1000,true)
1/** 2 * @desc 函数防抖 3 * @param func 函数 4 * @param wait 延迟执行毫秒数 5 * @param immediate true 表立即执行,false 表非立即执行 6 */ 7function debounce(func, wait, immediate) { 8 let timeout; 9 return function () { 10 const context = this; 11 const args = [...arguments]; 12 if (timeout) clearTimeout(timeout); 13 if (immediate) { 14 const callNow = !timeout; 15 timeout = setTimeout(() => { 16 timeout = null; 17 }, wait) 18 if (callNow) func.apply(context, args) 19 } 20 else { 21 timeout = setTimeout(() => { 22 func.apply(context, args) 23 }, wait); 24 } 25 } 26} 27
节流
所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。 节流会稀释函数的执行频率。
节流有两种实现:
- 时间戳版本
- 定时器版本
节流应用场景
scroll事件,每隔一秒计算一次位置信息等- 浏览器播放事件,每个一秒计算一次进度信息等
input输入框在搜索内容时,可以控制多少s 在执行请求,避免多次发起请求,节约性能。
时间戳版本
1function throttle(func, wait) { 2 var previous = 0; 3 return function() { 4 let now = Date.now(); 5 let context = this; 6 let args = arguments; 7 if (now - previous > wait) { 8 func.apply(context, args); 9 previous = now; 10 } 11 } 12} 13
定时器版本
1function throttle(func, wait) { 2 let timeout; 3 return function() { 4 let context = this; 5 let args = arguments; 6 if (!timeout) { 7 timeout = setTimeout(() => { 8 timeout = null; 9 func.apply(context, args) 10 }, wait) 11 } 12 13 } 14} 15
代码解析
当执行
throttle函数时,timeout默认为undefined, 此时,! timeout为true时,执行 定时器,并且 将timeout为 null,即为false, 再次执行throttle函数时,!timeout又为true,再次执行定时器。**通过
timeout的状态来达到节流的控制 **
总结
防抖: 触发事件后,一定时间后再执行事件,可以
立即执行也可以一定时间再执行节流: 控制流量,在单位时间内只能请求一次,避免多次触发事件,影响服务器性能。
结语
❤️关注+点赞+收藏+评论+转发❤️,原创不易,鼓励笔者创作更好的文章<br/><br/>关注公众号 <a href="https://z3.ax1x.com/2021/03/27/6zmqSI.jpg">前端自学社区</a>,即可获取更多前端高质量文章!<br/><br/>关注后回复关键词“加群”, 即可加入 “前端自学交流群”,共同学习进步。<br/><br/>关注后添加我微信拉你进技术交流群<br/><br/>欢迎关注公众号,更多精彩文章只在公众号推送
