企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
[TOC] # 函数节流 函数节流(throttle) 保证持续执行方法分隔为每 Xms 执行一次。 比如,乘坐地铁,过闸机时,每个人进入后 3 秒后门关闭,等待下一个人进入。 ## 应用场景: 1. DOM 元素的拖拽功能实现(mousemove) 2. 射击游戏的 mousedown/keydown 事件(单位时间只能发射一颗子弹),技能 CD 3. 计算鼠标移动的距离(mousemove) 4. Canvas 模拟画板功能(mousemove) 5. 搜索联想功能(keyup) 6. 滚动加载,加载更多或滚到底部监听 7. 就像每 200ms 监测滚动位置来触发 css 动画。 ``` function throttle(fn, delay) { var prevTime = Date.now(); return function() { var curTime = Date.now(); if (curTime - prevTime > delay) { fn.apply(this, arguments); prevTime = curTime; } }; } // 使用 var throtteScroll = throttle(function() { console.log('throtte'); }, 1000); window.onscroll = throtteScroll; ``` # 函数防抖 函数防抖(debounce)就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。 简单的说,当一个动作连续触发,则只执行最后一次。 比如,坐公交,司机需要等最后一个人进入才能关门。每次进入一个人,司机就会多等待几秒再关门。 ## Debounce Implementations(实现) 2009 年在 John Hann 的文章中第一次看到 debounce 的实现方法。 在那之后不久,Ben Alman 写了一个 jQuery 插件 (现在不在维护),一年以后 Jeremy Ashkenas 把此方法添加到 underscore.js 中,不久又被添加到 lodash 中。 这三种实现方法内部不同,但是接口几乎一致。 有段时间 underscore 采用了 Lodash 的实现方法,后来两个库的实现开始分道扬镳。 Lodash 在`_.debounce`和`_.throttle`中添加了许多特性。immediate 标示替代了 leading 和 trailing。你可以二选一或者都选,默认情况下,只有 trailing 是开启的。 ``` function debounce(func, wait) { let timeout; return function() { let context = this; let args = arguments; if (timeout) clearTimeout(timeout); timeout = setTimeout(() => { func.apply(context, args); }, wait); }; } // 使用 window.onscroll = debounce(function() { console.log('debounce'); }, 1000); ``` ## 应用场景: 1. 搜索框搜索输入。只需用户最后一次输入完,再发送请求 2. 手机号、邮箱验证输入检测 3. 窗口大小 Resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。 # 异同比较 相同点: 都可以通过使用 setTimeout 实现。 目的都是,降低回调执行频率,节省计算资源。 不同点: 函数防抖,在一段连续操作结束后,处理回调,利用 clearTimeout 和 setTimeout 实现。函数节流,在一段连续操作中,每一段时间只执行一次,频率较高的事件中使用来提高性能。 函数防抖关注一定时间连续触发,只在最后执行一次,而函数节流侧重于一段时间内只执行一次。 # 源码学习 可以访问这个 [在线演示](http://demo.nimius.net/debounce_throttle/) 来查看 Debounce、Throttle 和默认情况的事件监听效果。 建议先看下 lodash 里 debounce 和 throttle 的用法: [debounce](https://www.lodashjs.com/docs/latest#_debouncefunc-wait0-options) [throttle](https://www.lodashjs.com/docs/latest#_throttlefunc-wait0-options) # 参考 See[David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)for details over the differences between[`_.debounce`](https://www.lodashjs.com/docs/latest#debounce)and[`_.throttle`](https://www.lodashjs.com/docs/latest#throttle) [underscore throttle 与 debounce 节流](https://zhuanlan.zhihu.com/p/26054718)