防抖与节流
- 防抖:当连续调用时间间隔小于
delay时,只执行最后一次调用
- 节流:某段时间内多次调用,只生效第一次,(限制某段时间内的调用次数,次数为1且是第一次)
- 参考文章
- 目的: 优化一个被频繁调用/触发的函数/事件
- 防抖应用:比如当用户在快速输入时,不应每次输入都调用请求,而是当用户一定时间内未再输入,再调用请求
- 节流应用:比如限制用户的调用请求,避免用户快速点击请求的时候,频繁向后台发送请求,而是第一次调用后,再间隔一定时间后才能继续调用下一次。
- 在
ts中可以使用装饰器Decorators修饰函数,使其成为防抖/节流函数
防抖
Vue自定义防抖ref
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 34
| <template> <h1>自定义防抖ref</h1> <input v-model="text" /> <div>{{ text }}</div> </template> <script setup lang="ts"> import { customRef } from 'vue'; /** * 自定义防抖ref * @param value 值 * @param delay 延迟时间, 默认500ms */ function debounceRef(value: any, delay:number = 500){ let timer: number; // customRef 的参数是一个函数, 其参数有track和trigger两个, 返回一个带有get,set的对象 return customRef((track, trigger) => { return { get() { track(); return value; }, set(newVal: any) { clearTimeout(timer); // timer赋值 timer = setTimeout(() => { value = newVal; trigger(); }, delay) } } }) } const text = debounceRef(''); </script>
|
防抖装饰器
1 2 3 4 5 6 7 8 9 10
| export default (fun: Function, delay: number = 500) => { let timer: number; return function (this: unknown, ...args: any[]) { clearTimeout(timer); timer = setTimeout(() => { fun.apply(this, args) }, delay) } }
|
1 2 3 4 5 6 7 8 9 10
| function debounce(fun, delay = 500) { let timer = null; return function (...args) { clearTimeout(timer); timer = setTimeout(() => { fun.apply(this, args) }, delay) } }
|
节流
Lodash: https://www.lodashjs.com/docs/lodash.throttle#_throttlefunc-wait0-options
Lodash节流函数源码: https://github.com/lodash/lodash/blob/master/throttle.js
现代JS教程: https://zh.javascript.info/task/throttle
1 2 3 4 5 6 7 8 9 10 11
| function throttle(func, wait=1000) { let timer = null; return function(...args) { if (!timer) { timer = setTimeout(() => { func.apply(this, args); timer = null; }, wait); } }; }
|