函数节流(throttling) 与 防抖(debounce)
节流和防抖,是限制事件高频率触发 ,这类问题的解决方案,如,滚动条的滚动监听、频繁点击按钮、窗口缩放等,这类事件瞬间频繁触发,会导致性能飙升,程序卡顿。
节流:一个时间周期内的重复事件,仅触发一次。在连续高频触发事件时,动作会被定期执行,响应平滑。如,快速点击按钮提交网络请求,如果1s内重复点击了多次,可能会发起多次请求,节流策略会限制1s 的周期内,只会发起一次网络请求。
时间戳方式:
function throttle(fn, gapTime) { if (gapTime == null || gapTime == undefined) { gapTime = 1500 } let _lastTime = null return function () { let _nowTime = + new Date() if (_nowTime - _lastTime > gapTime || !_lastTime) { fn.apply(this, arguments) //将this和参数传给原函数 _lastTime = _nowTime } } }
定时器方式:
function throttle ( fn, delay){ var timer; var isThrottle = false; return function (){ var _this = this var args = arguments if(!isThrottle){ isThrottle = true fn.apply(_this,args) timer = setTimeout(()=>{ clearTimeout(timer) isThrottle = false },delay || 1000) } } }
调用方式:
// 对象方法
Page({ ... handle: throttle(function () { console.log(this) }, 500) ... })
// 事件绑定
btn.onclick = throttle( function(){}, 1000 )
防抖:事件持续触发时,会增加一个时间延迟,期间再次触发,会重置这个延迟,直到延迟结束,才会执行事件。当事件快速连续不断触发时,只会在动作结束时执行一次。如,调整窗口大小时,会频繁触发 onresize 事件,防抖策略,会限制事件在间歇的空挡期执行,或操作完之后执行。
function debounce(fn, delay) { let timer = null; return function () { let ctx = this; let args = arguments; if (timer) { clearTimeout(timer); timer = null; } timer = setTimeout(function () { fn.apply(ctx, args); timer = null; }, delay); }; }