Appearance
debounce 防抖函数
在高频触发场景(输入、滚动、窗口尺寸变化等)中,防抖可将多次触发合并为最后一次触发后的执行,有效减少不必要的计算或请求。
安装与引入
按需导入(推荐)
ts
import { debounce } from '@cuixingjian/cui-utils'子路径导入
ts
import { debounce } from '@cuixingjian/cui-utils/debounce'效果演示
基础用法
输入内容后,等待 300ms 才会触发搜索,频繁输入只会执行最后一次。
使用代码
基础防抖:
ts
import { debounce } from '@cuixingjian/cui-utils'
const onSearch = (keyword: string) => {
console.log('搜索:', keyword)
}
const onSearchDebounced = debounce(onSearch, 300)立即执行模式:
ts
import { debounce } from '@cuixingjian/cui-utils'
const save = (data: any) => {
console.log('保存数据:', data)
}
const saveDebounced = debounce(save, 500, { immediate: true })取消与立即触发:
ts
import { debounce } from '@cuixingjian/cui-utils'
const handler = debounce(() => {
console.log('执行处理')
}, 300)
// 取消等待中的调用
handler.cancel()
// 立即执行最后一次的调用(如果存在)
handler.flush()API 说明
函数签名
ts
function debounce<T extends (...args: any[]) => any>(
fn: T,
wait?: number,
options?: DebounceOptions
): DebouncedFn<T>参数
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| fn | (...args: any[]) => any | — | 需要防抖的函数 |
| wait | number | 200 | 等待时间(毫秒) |
| options | DebounceOptions | {} | 配置选项 |
DebounceOptions
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| immediate | boolean | false | 是否在首次触发时立即执行 |
返回值
返回一个防抖函数 DebouncedFn<T>,具有以下方法:
| 方法 | 类型 | 说明 |
|---|---|---|
| cancel | () => void | 取消等待中的调用 |
| flush | () => void | 立即执行最后一次的调用(如果存在) |
注意事项
基本规则
- 在组件卸载前如仍有防抖等待中的调用,建议调用
cancel()进行清理 - 防抖函数会保留
this上下文和参数
immediate 模式说明
immediate: true时,首次触发会立即执行- 在等待窗口内的后续触发被合并
- 等待窗口关闭后不再触发尾调用
典型场景
- 搜索框输入:用户停止输入后再发起请求
- 窗口尺寸变化:调整完成后再重新计算布局
- 表单验证:输入停止后再进行验证
- 自动保存:编辑停止后自动保存草稿
源码
展开查看
ts
export interface DebounceOptions {
immediate?: boolean
}
export interface DebouncedFn<T extends (...args: any[]) => any> {
(...args: Parameters<T>): void
cancel: () => void
flush: () => void
}
export function debounce<T extends (...args: any[]) => any>(
fn: T,
wait = 200,
options: DebounceOptions = {}
): DebouncedFn<T> {
let timer: ReturnType<typeof setTimeout> | null = null
let lastArgs: Parameters<T> | null = null
let lastThis: any = null
const { immediate = false } = options
const invoke = () => {
if (lastArgs) {
fn.apply(lastThis, lastArgs)
lastArgs = null
lastThis = null
}
}
const debounced = function (this: any, ...args: Parameters<T>) {
lastArgs = args
lastThis = this
if (timer) {
clearTimeout(timer)
timer = null
}
if (immediate && !timer) {
fn.apply(this, args)
}
timer = setTimeout(() => {
if (!immediate) {
invoke()
}
timer = null
}, wait)
} as DebouncedFn<T>
debounced.cancel = () => {
if (timer) {
clearTimeout(timer)
timer = null
}
lastArgs = null
lastThis = null
}
debounced.flush = () => {
if (timer) {
clearTimeout(timer)
timer = null
}
invoke()
}
return debounced
}