debounce
创建一个防抖函数,延迟执行直到停止调用一段时间。
基础用法
typescript
import { debounce } from 'radash'
const debouncedSearch = debounce(async (query: string) => {
const response = await fetch(`/api/search?q=${query}`)
return response.json()
}, 300)
// 用户输入时,只有在停止输入300ms后才会执行搜索
debouncedSearch('hello')
debouncedSearch('hello world')
debouncedSearch('hello world example')
// 只有最后一次调用会执行
语法
typescript
function debounce<T extends (...args: any[]) => any>(
fn: T,
delay: number,
options?: {
immediate?: boolean
}
): (...args: Parameters<T>) => void
参数
fn
(function): 要防抖的函数delay
(number): 延迟时间(毫秒)options
(object, 可选): 配置选项immediate
(boolean, 可选): 是否立即执行第一次调用,默认为false
返回值
返回一个防抖后的函数。
示例
基本防抖
typescript
import { debounce } from 'radash'
const debouncedLog = debounce((message: string) => {
console.log('Debounced:', message)
}, 500)
// 多次快速调用
debouncedLog('hello')
debouncedLog('hello world')
debouncedLog('hello world example')
// 只有最后一次调用会在500ms后执行
搜索输入防抖
typescript
import { debounce } from 'radash'
const searchInput = document.getElementById('search') as HTMLInputElement
const debouncedSearch = debounce(async (query: string) => {
if (query.length < 2) return
const response = await fetch(`/api/search?q=${encodeURIComponent(query)}`)
const results = await response.json()
displayResults(results)
}, 300)
searchInput.addEventListener('input', (e) => {
const query = (e.target as HTMLInputElement).value
debouncedSearch(query)
})
function displayResults(results: any[]) {
// 显示搜索结果
console.log('Search results:', results)
}
窗口大小调整防抖
typescript
import { debounce } from 'radash'
const debouncedResize = debounce(() => {
console.log('Window resized to:', window.innerWidth, 'x', window.innerHeight)
// 重新计算布局
recalculateLayout()
}, 250)
window.addEventListener('resize', debouncedResize)
function recalculateLayout() {
// 重新计算页面布局
console.log('Layout recalculated')
}
表单提交防抖
typescript
import { debounce } from 'radash'
const debouncedSubmit = debounce(async (formData: FormData) => {
try {
const response = await fetch('/api/submit', {
method: 'POST',
body: formData
})
if (!response.ok) {
throw new Error('Submit failed')
}
const result = await response.json()
console.log('Form submitted successfully:', result)
} catch (error) {
console.error('Submit error:', error)
}
}, 1000)
const form = document.getElementById('myForm') as HTMLFormElement
form.addEventListener('submit', (e) => {
e.preventDefault()
const formData = new FormData(form)
debouncedSubmit(formData)
})
立即执行模式
typescript
import { debounce } from 'radash'
const debouncedFunction = debounce((value: string) => {
console.log('Executed with:', value)
}, 500, { immediate: true })
// 第一次调用会立即执行
debouncedFunction('first') // 立即执行
debouncedFunction('second') // 延迟500ms后执行
debouncedFunction('third') // 延迟500ms后执行
API调用防抖
typescript
import { debounce } from 'radash'
const debouncedApiCall = debounce(async (params: any) => {
const response = await fetch('/api/data', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(params)
})
return response.json()
}, 300)
// 在用户操作时调用
async function handleUserAction() {
const params = { action: 'update', data: { /* ... */ } }
const result = await debouncedApiCall(params)
console.log('API result:', result)
}
滚动事件防抖
typescript
import { debounce } from 'radash'
const debouncedScroll = debounce(() => {
const scrollTop = window.pageYOffset || document.documentElement.scrollTop
console.log('Scrolled to:', scrollTop)
// 更新滚动指示器
updateScrollIndicator(scrollTop)
}, 100)
window.addEventListener('scroll', debouncedScroll)
function updateScrollIndicator(scrollTop: number) {
const indicator = document.getElementById('scroll-indicator')
if (indicator) {
indicator.style.width = `${(scrollTop / (document.body.scrollHeight - window.innerHeight)) * 100}%`
}
}
键盘事件防抖
typescript
import { debounce } from 'radash'
const debouncedKeyPress = debounce((key: string) => {
console.log('Key pressed:', key)
// 处理键盘输入
processKeyInput(key)
}, 200)
document.addEventListener('keydown', (e) => {
debouncedKeyPress(e.key)
})
function processKeyInput(key: string) {
// 处理键盘输入逻辑
console.log('Processing key:', key)
}
鼠标移动防抖
typescript
import { debounce } from 'radash'
const debouncedMouseMove = debounce((x: number, y: number) => {
console.log('Mouse position:', x, y)
// 更新鼠标位置显示
updateMousePosition(x, y)
}, 50)
document.addEventListener('mousemove', (e) => {
debouncedMouseMove(e.clientX, e.clientY)
})
function updateMousePosition(x: number, y: number) {
const positionElement = document.getElementById('mouse-position')
if (positionElement) {
positionElement.textContent = `X: ${x}, Y: ${y}`
}
}
复杂参数防抖
typescript
import { debounce } from 'radash'
interface SearchParams {
query: string
filters: Record<string, any>
page: number
}
const debouncedSearch = debounce(async (params: SearchParams) => {
const queryString = new URLSearchParams({
q: params.query,
page: params.page.toString(),
...params.filters
}).toString()
const response = await fetch(`/api/search?${queryString}`)
const results = await response.json()
return {
results,
total: results.length,
page: params.page
}
}, 500)
// 使用防抖搜索
async function performSearch() {
const params: SearchParams = {
query: 'javascript',
filters: { category: 'programming', sort: 'relevance' },
page: 1
}
const result = await debouncedSearch(params)
console.log('Search result:', result)
}
取消防抖函数
typescript
import { debounce } from 'radash'
const debouncedFunction = debounce((message: string) => {
console.log('Executed:', message)
}, 1000)
// 调用函数
debouncedFunction('hello')
// 取消延迟执行
// 注意:radash的debounce不直接支持取消,但可以通过重新创建函数来实现
const cancelDebounce = () => {
// 重新创建防抖函数来"取消"之前的调用
const newDebouncedFunction = debounce((message: string) => {
console.log('Executed:', message)
}, 1000)
return newDebouncedFunction
}
多个防抖函数
typescript
import { debounce } from 'radash'
// 创建多个不同延迟的防抖函数
const quickDebounce = debounce((action: string) => {
console.log('Quick action:', action)
}, 100)
const mediumDebounce = debounce((action: string) => {
console.log('Medium action:', action)
}, 500)
const slowDebounce = debounce((action: string) => {
console.log('Slow action:', action)
}, 1000)
// 使用不同的防抖函数
quickDebounce('fast')
mediumDebounce('normal')
slowDebounce('slow')
条件防抖
typescript
import { debounce } from 'radash'
const conditionalDebounce = debounce((value: string, shouldExecute: boolean) => {
if (shouldExecute) {
console.log('Executing with value:', value)
// 执行实际逻辑
processValue(value)
}
}, 300)
function processValue(value: string) {
// 处理值的逻辑
console.log('Processing:', value)
}
// 根据条件决定是否执行
conditionalDebounce('test', true)
conditionalDebounce('skip', false)
conditionalDebounce('execute', true)
注意事项
- 延迟时间: 选择合适的延迟时间,太短可能无效,太长影响用户体验
- 内存泄漏: 防抖函数会保持对原函数的引用
- 立即执行: 使用immediate选项可以立即执行第一次调用
- 异步函数: 防抖函数可以包装异步函数
- 参数传递: 防抖函数会传递所有参数给原函数
与其他方法的区别
throttle()
: 限制执行频率,防抖是延迟执行debounce()
: 等待停止调用后执行- 手动实现: 需要更多代码和错误处理
实际应用场景
- 搜索输入: 防止频繁的API调用
- 窗口调整: 优化布局重新计算
- 表单提交: 防止重复提交
- 滚动事件: 优化滚动处理
- 键盘事件: 减少键盘事件处理频率