防抖和节流严格算起来应该属于性能优化的知识,但实际上遇到的频率相当高,处理不当或者放任不管就容易引起浏览器卡死。所以还是很有必要早点掌握的。
防抖和节流的区别:
节流是将多次执行变为每隔一段时间执行(多次点击,在时间内,只执行第一次)
防抖是将多次执行变为最后一次执行(多次点击,只执行最后一次)
函数节流(throttle):当持续触发事件时,保证在一定时间内只调用一次事件处理函数
实现函数节流我们主要有两种方法:时间戳和定时器
时间戳方法: 利用时间戳让第一次执行事件,此后每隔3000ms 执行,小于这段时间不会执行
定时器方法:先将设置的定时器设置为null,第一次触发事件,达到时间后再执行这个函数,并初始化定时器
使用方法:先在data中定义字段,在methods中定义节流方法及使用 //定义节流时间(data中定义字段) preTime:0, /*节流方法(时间戳精简版) //1.先定义一个 preTime = 0 赋予初始值 ,为第一次点击 //2.获取当前时间戳 - preTime 判断是否大于延迟时间 //3.执行之后 将now 当前时间的时间戳进行赋值 preTime */ throttle(fn, delay = 3000) { let pre = this.preTime // 初始值是 0 let that = this return function() { let now = +new Date(); if (now - pre >= delay) { fn.apply(this, arguments) that.preTime = now; } } }, //使用方法 toSaveGoods(){ let that = this ; //节流方法 this.throttle(function(){ that.saveGoods();//执行的方法 },3000)() }, /** 节流方法集成版 * @param { function } func 函数 * @param { number } wait 延迟执行毫秒数 * @param { number } type 1 表时间戳版,2 表定时器版 */ 先定义要使用的属性(data中定义字段) previous:0, timeout:null, throttle_pro(func, wait ,type) { let that = this; console.log(' throttle_pro -->',type) let previous, timeout; if(type===1){ previous = this.previous; }else if(type===2){ timeout = this.timeout; } return function() { let context = this; // arguments 是一个对应于传递给函数的参数的类数组对象 let args = arguments; if(type===1){ let now = Date.now(); if (now - previous >= wait) { func.apply(context, args); that.previous = now; } }else if(type===2){ if (!timeout) { that.timeout = setTimeout(() => { that.timeout = null; func.apply(context, args) }, wait) } } } }, toPerformThrottle_pro(type){ let that = this; //节流方法 this.throttle_pro(function() { //that.saveGoods();//执行的方法 that.toPerform_pro(); }, 3000,type)() }, toPerform_pro(){ console.log(' 集成版的节流 '); }效果展示:
防抖(debounce):所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
防抖函数分为:非立即执行版和立即执行版。
//防抖,定义一个定时器 (data中定义字段) debounce_timeout:null, //防抖优化版 d_timeout:null /* 函数的防抖 //( 滚动加载时使用较好,当持续触发事件时,一定时间段内没有再触发事件, //事件处理函数才会执行一次 ) */ debounce(fn, wait) { let that = this let timeout = this.debounce_timeout; //定义一个定时器 return function() { if(timeout !== null) clearTimeout(that.debounce_timeout); //清除这个定时器 that.debounce_timeout = setTimeout(fn, wait); } }, debouncePerform(){ let that = this; this.debounce(function() { that.debounceConsole(); }, 3000)() }, debounceConsole(){ console.log(' 执行防抖函数 '); }, /** * 函数防抖优化版 * @param { function } func * @param { number } wait 延迟执行毫秒数 * @param { boolean } immediate true 表立即执行,false 表非立即执行 */ debounce_pro(func,wait,immediate) { let that = this; let timeout = this.d_timeout; // 获取定义的定时器 return function () { let context = this; let args = arguments; if (timeout) clearTimeout(timeout); //有值,清除定时器任务 if (immediate) { let callNow = !timeout; that.d_timeout = setTimeout(() => { that.d_timeout = null; }, wait); if (callNow) func.apply(context, args) }else { that.d_timeout = setTimeout(() => { func.apply(context, args) }, wait); } } }, debouncePerformPro(immediate){ let that = this; this.debounce_pro(function() { that.debounceConsole(); }, 3000,immediate)() }效果展示:
