throttle
概念:触发函数事件后,短时间间隔内无法连续调用,只有上一次函数执行后,过了规定的时间间隔,才能进行下一次的函数调用 适用场景:窗口调整(resize)、页面滚动(scroll)、抢购疯狂点击(movedown)
function throttle(fn, interval) { let last = 0; return function() { let context = this; let args = arguments; let now = new Date.getTime(); if(now - last >= interval) { fn.apply(context, args); last = now; } }}复制代码
debounce
在特定时间延迟内连续多次触发事件后,事件处理函数只执行一次,并且是在触发操作结束时执行 适用场景: 实时搜索(keyup)、拖拽(mousemove)
function debounce(fn, delay) { let timer = null; return function () { let context = this; let args = arguments; clearTimeout(timer); timer = setTimeout(function() { fn.apply(this, args); }, delay); }}复制代码
## 用 Throttle 来优化 Debounce
如果用户的操作十分频繁——每次都不等 debounce 设置的 delay 时间结束就进行下一次操作,于是每次 debounce 都为该用户重新生成定时器,回调函数被延迟了不计其数次。频繁的延迟会导致用户迟迟得不到响应,用户同样会产生“这个页面卡死了”的观感。
为了避免这个问题,我们需要改进:delay的时间到了,必须要给用户一个响应,也就是要调用一次执行函数。
function throttle(fn, delay) { let timer = null, last = 0; return function() { let context = this; let args = arguments; let now = new Date.getTime(); // 确保delay的时间内至少执行一次 if (now - last >= delay) { fn.apply(this, args); last = now; } else { clearTimeout(timer); timer = setTimeout(function() { last = now; fn.apply(this, args); }, delay); } } }复制代码