0%
|
防抖 debounce |
节流 throttle |
概念 |
任务频繁触发的情况下间隔时间超过指定值的时候才会执行 时间间隔不定, 连续不断的触发, 比如校验用户输入 在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时 |
任务频繁触发的情况下指定间隔内只会执行一次任务 时间周期固定 规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。 |
理解 |
函数防抖就是法师发技能的时候要读条,技能读条没完再按技能就会重新读条。 必须等读条完毕才能发出技能,否则重新计时, 这个很关键. |
函数节流就是fps游戏的射速,就算一直按着鼠标射击,也只会在规定射速内射出子弹。
|
场景 |
- search搜索联想,用户在不断输入值时,用防抖来节约请求资源。
- window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次

前缘(或者“immediate”)

|
- 鼠标不断点击触发,mousedown(单位时间内只触发一次)
- 监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断
|-1-|-3-|-2-|-4-|-2-|-4-|-3-|-0-|-1-|-2-|-3-|-4-|-0-|-1-| 如上所示:每个时间周期内都可能会有多次任务触发,但是每次只会执行一个,这就是节流,那么如何实现呢?
|
原理 |
- 通过闭包保存setTimeout返回值,
- 当用户持续输入时, clearTimeout(清理延时任务),
- 设置新的延时任务
- 这样可以保证用户持续输入时每次重置延时任务, 等用户停止输入才会开始执行函数
|
- 通过闭包保存一个标记, 在函数开头判断标记是否可用, 可用执行,否则返回.
- 外部函数定期执行, 完毕标记重置
|
实现 |
1 2 3 4 5 6 7 8 9 10 11 12
| function debounce(fn, interval = 300) { let timerID = null; function run() { if (timerID) clearTimeout(timerID);
timerID = setTimeout(() => { fn.apply(this.arguments); }, interval); }
return run; }
|
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| function throttle(fn, interval = 300) { let running = false; function run() { if (running) return; running = true; timerID = setTimeout(() => { fn.apply(this, arguments); running = false; }, interval); }
return run; }
|
|
总结 |
函数防抖和函数节流都是防止某一时间频繁触发,但是这两兄弟之间的原理却不一样。 |
函数防抖是某一段时间内只执行一次,而函数节流是间隔时间执行。 |