防抖和节流的目的都是希望一段时间内不要密集调用callback。
应用场景:滚动(防抖),搜索(节流)
防抖
所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
有些事件比如 resize, scroll, mousemove 等会被持续的触发,导致 callback
被高频调用,这就要用到防抖。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
function debounce(func, wait, immediate) { let timeout;
return function() { let context = this; let args = arguments;
if (timeout) clearTimeout(timeout);
if (immediate) { var callNow = !timeout;
timeout = setTimeout(() => { timeout = null; }, wait); if (callNow) func.apply(context, args); } else { timeout = setTimeout(function() { func.apply(context, args); }, wait); } }; }
|
节流
所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。
时间戳版和定时器版的节流函数的区别是:时间戳版的函数触发是在时间段内开始的时候,而定时器版的函数触发是在时间段内结束的时候。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
function throttle(func, wait, type) { if (type === 1) { let previous = 0; } else if (type === 2) { let timeout; } return function() { let context = this; let args = arguments;
if (type === 1) { let now = Date.now();
if (now - previous > wait) { func.apply(context, args); previous = now; } } else if (type === 2) { if (!timeout) { timeout = setTimeout(() => { timeout = null; func.apply(context, args); }, wait); } } }; }
|
总结
防抖是控制次数,节流是控制频率。
ref
- 简版 debounce 和 throttle