防抖与节流的实现原理和区别
- 函数防抖(debounce)和 函数节流(throttle)都是为了限制函数的执行频次,来优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟,假死或卡顿的现象(例如input,keyup,keydown,scroll,resize,mousemove等)
- 函数防抖: 触发完事件 n 秒内不再触发,才执行;如果n秒内事件再次被触发,则重新计算时间
- 应用场景:
- 用户在输入框中连续输入一串字符后,只会在输入完后去执行最后一次的查询ajax请求,这样可以有效减少请求次数,节约请求资源
- window的resize、scroll事件,不断地调整浏览器的窗口大小、或者滚动时会触发对应事件,防抖让其只触发一次
函数节流: 持续触发事件,每隔一段时间,只执行一次事件(类似于技能冷却时间)function debounce(fn,delay = 100){ // 创建一个标记用来存放定时器的返回值 let timer = null return function (){ // 每当事件触发的时候把前一个 setTimeout清除 if(timer) clearTimer(timer) // 然后又创建一个新的 setTimeout, 这样就能保证时间间隔内如果事件持续触发,就不会执行 fn 函数 timer = setTimeout(() => { fn.apply(this,arguments) timer = null },delay) } }
应用场景:- 连续不断地触发某事件(如点击),只在单位时间内只触发一次
function throttle(fn,delay = 100){ // 通过闭包保存一个标记,相当于一个开关 let flag = true return function () { // 在函数开头判断标记定时器是否触发,如果有值return if (!flag) return flag = false setTimeout(() => { fn.apply(this, arguments) flag = true }, delay) } }
- 区别:
- 防抖在多次(频繁)触发事件时,只会执行最后一次触发,不停止触发事件的行为就不会执行事件处理
- 节流在多次(频繁)触发事件时,能保证在指定时间内一定会且只会触发一次