防抖
使用场景: 输入框输入搜索,拖拽( mousemove )
效果: 不是每次操作后执行函数.在频繁操作的最后一次操作结束后在设置的时间内没有触发操作时才执行回调
两种思路
- 立即执行: 在第一次触发事件的时候立即执行当前操作的回调,后面的操作在最后一次操作结束后在设置的时间内没有触发操作时才执行回调
- 无立即执行: 按最后一次操作结束后的规定时间执行
function debounce(fn, delay, immediate) { let timer; //利用闭包保存同一个timer return function () { let self = this; let arg = arguments; clearTimeout(timer); if (immediate) { const callNow = !timer; timer = setTimeOut(() => { timer = null; }, delay); if (callNow) fn.apply(self.arg); } else { timer = setTimeout(() => { fn.apply(self, arg); }, delay); } }; }
节流
使用场景:滚动条滚动,频繁点击请求接口
效果:预定一个函数只有在大于等于执行周期时才执行
两种思路:
- 时间戳,先会立即执行,达到时间周期再执行
function throttle(fn, delay) { let t; return function () { let self = this; let arg = arguments; if (!t || Date.now() - t >= delay) { fn.apply(self, arg); t = new Date(); } }; }
- 定时器,定时一定时间周期之后去执行,但是在这时间内中不停的调用,不让他的定时器清零重新计时,不会影响当前的结果,还是那时间继续等,等到达时间周期后触发(会出现停止操作还是会触发)
function throttle(fn,delay) { let timer retrun function () { let self = this let arg = arguments if(timer) return timer = setTimeOut(()=> { fn.apply(fn,arg) timer = null },delay) } }