防抖和节流在很多场景下都可以有效的提升程序的性能和减轻服务器的压力.估计大多数人都使用过这两个工具函数(例如在lodash中以函数或装饰器的模式to use)那么如何实现自己的防抖和节流函数呢?
-
定义
- 防抖: 在n秒后不被重复触发才会执行
- 节流: 在规定的n秒内有且只执行一次
-
实现(具体思路的在注释中体现,因为并不复杂)
- 防抖
/** * 函数防抖 * @param fn 频繁触发的函数 type Function * @param delay 延迟 type Number * @param immediate 是否立即触发一次 type Boolean */ const debounce = (fn, delay = 300, immediate = false) => { let timer = null; let now = true; let result; return function() { clearTimeout(timer); // 如果设置立即触发则立即触发 if (immediate) { // 如果是第一次 则立即触发 if (now) { result = fn.apply(this, arguments); now = false; } else { timer = setTimeout(() => { // 绑定this和event对象 fn.apply(this, arguments) }, delay); } } else { // 如果没设置立即触发则按延时触发 timer = setTimeout(() => { fn.apply(this, arguments) }, delay); } return result }; }
- 节流
/** * 函数节流 * @param fn 频繁触发的函数 type Function * @param delay 延迟 type Number * @param limit 必触发时间限制 type Number */ const throttle = (fn, delay = 300, limit = 1000) => { let timer = null; let previous = null; let result; return function() { // 记录当前时刻 let now = +new Date(); // 记录上次开始时间 !previous && (previous = now); // 达到限制时间手动触发一次函数执行 if (now - previous > limit) { // 绑定this和event对像 result = fn.apply(this, arguments); // 重置上一次开始时间为本次结束时间 previous = now; } else { // 限制在规定时间内重复触发无效 clearTimeout(timer); timer = setTimeout(() => { fn.apply(this, arguments) }, delay); } return result; } }