关于 tanstack-pacer
tanstack-pacer 是用于控制函数执行时机的类型安全工具包,面向 TypeScript 与 React 开发者。它以类、工厂函数和 React Hooks 提供防抖、节流、限流、队列与批处理能力。
主要功能
- 01防抖与节流
- 02按时间窗口限流
- 03可配置并发的队列
- 04按数量或时间批处理
- 05类、工厂函数与 React Hooks
适用场景
- 01延迟搜索输入处理
- 02限制滚动事件更新频率
- 03顺序处理文件上传任务
- 04合并分析事件后发送
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ tanstack-skills/ tanstack-skills --skill tanstack-pacer安装后在 Claude Code 中输入/tanstack-pacer确认已加载。
详细介绍
概览
TanStack Pacer 提供统一且类型安全的工具包,用于控制函数的执行时机。它提供基于类的 API、工厂函数和 React Hook,可用于防抖、节流、速率限制、排队和批处理。
核心: @tanstack/pacer
React: @tanstack/react-pacer
状态: Beta
安装
npm install @tanstack/pacer
npm install @tanstack/react-pacer # React hooks
防抖
在一段时间内没有活动后再执行。
类 API
import { Debouncer } from '@tanstack/pacer'
const debouncer = new Debouncer(
(query: string) => fetchSearchResults(query),
{
wait: 300, // ms of inactivity before execution
leading: false, // Execute on leading edge (default: false)
trailing: true, // Execute on trailing edge (default: true)
maxWait: 1000, // Force execution after 1s of continuous calls
enabled: true,
onExecute: (result) => console.log(result),
}
)
debouncer.maybeExecute('search term')
debouncer.cancel()
debouncer.getExecutionCount()
debouncer.setOptions({ wait: 500 }) // Dynamic reconfiguration
工厂函数
import { debounce } from '@tanstack/pacer'
const debouncedSearch = debounce(
(query: string) => fetchResults(query),
{ wait: 300 }
)
debouncedSearch('term')
debouncedSearch.cancel()
React Hook
import {
useDebouncer,
useDebouncedCallback,
useDebouncedState,
useDebouncedValue,
} from '@tanstack/react-pacer'
// Full debouncer instance
const debouncer = useDebouncer(fn, { wait: 300 })
// Simple debounced function
const debouncedFn = useDebouncedCallback(fn, { wait: 300 })
// Debounced state management
const [debouncedValue, setValue] = useDebouncedState(initialValue, { wait: 300 })
// Debounced reactive value
const debouncedValue = useDebouncedValue(reactiveValue, { wait: 300 })
节流
限制每个时间间隔内最多执行一次。
类 API
import { Throttler } from '@tanstack/pacer'
const throttler = new Throttler(
(position: { x: number; y: number }) => updatePosition(position),
{
wait: 100, // Minimum interval between executions
leading: true, // Execute immediately on first call (default: true)
trailing: true, // Execute after interval with last args (default: true)
enabled: true,
onExecute: (result) => console.log(result),
}
)
throttler.maybeExecute({ x: 100, y: 200 })
throttler.cancel()
React Hook
import {
useThrottler,
useThrottledCallback,
useThrottledState,
useThrottledValue,
} from '@tanstack/react-pacer'
const throttledFn = useThrottledCallback(handleScroll, { wait: 100 })
const [throttledPos, setPos] = useThrottledState({ x: 0, y: 0 }, { wait: 100 })
速率限制
控制执行频率,限制在一个时间窗口内的最大调用次数。
类 API
import { RateLimiter } from '@tanstack/pacer'
const limiter = new RateLimiter(
async (endpoint: string) => fetch(endpoint).then(r => r.json()),
{
limit: 10, // Max executions per window
window: 60000, // Time window in ms (60s)
enabled: true,
onExecute: (result) => console.log(result),
onReject: (...args) => console.warn('Rate limited:', args),
}
)
limiter.maybeExecute('/api/data') // Rejected if limit exceeded
limiter.getExecutionCount()
limiter.getRejectionCount()
React Hook
import {
useRateLimiter,
useRateLimitedCallback,
useRateLimitedState,
useRateLimitedValue,
} from '@tanstack/react-pacer'
const rateLimitedFn = useRateLimitedCallback(apiCall, { limit: 5, window: 1000 })
排队
按顺序执行,并可配置并发数。
import { Queue } from '@tanstack/pacer'
const queue = new Queue({
concurrency: 1, // Max concurrent tasks
started: true, // Start processing immediately
})
queue.add(() => uploadFile(file1))
queue.add(() => uploadFile(file2))
queue.start()
queue.pause()
queue.clear()
queue.getSize() // Pending count
queue.getPending() // Currently executing count
批处理
将多次调用合并处理。
import { Batcher } from '@tanstack/pacer'
const batcher = new Batcher(
(items: LogEntry[]) => sendBatchToServer(items),
{
maxSize: 50, // Auto-flush at 50 items
wait: 1000, // Auto-flush after 1s
}
)
batcher.add(logEntry) // Accumulates
batcher.flush() // Manual flush
batcher.getSize() // Current batch size
batcher.clear() // Discard batch
异步变体
import { AsyncDebouncer, asyncDebounce, AsyncThrottler, asyncThrottle } from '@tanstack/pacer'
const asyncDebouncer = new AsyncDebouncer(
async (query: string) => {
const response = await fetch(`/api/search?q=${query}`)
return response.json()
},
{ wait: 300 }
)
// React async hooks
import { useAsyncDebouncer, useAsyncThrottler } from '@tanstack/react-pacer'
选择合适的工具
| 场景 | 工具 | 原因 |
|---|---|---|
| 搜索输入 | 防抖器 | 等待用户停止输入 |
| 滚动事件 | 节流器 | 活动期间定期更新 |
| API 防护 | RateLimiter | 严格限制调用频率 |
| 文件上传 | Queue | 按顺序处理 |
| 分析事件 | Batcher | 分组以提高效率 |
| 网络请求 | AsyncDebouncer | 处理中止/重试 |
前沿与后沿
- 前沿(
leading: true):立即执行,在等待时间结束前抑制后续执行。适用于按钮点击。 - 后沿(
trailing: true):活动停止后执行。适用于搜索输入。 - 两者兼用:立即执行,并在最后一次等待结束后再次执行。适用于滚动节流。
最佳实践
- 防抖时使用
maxWait,确保持续活动期间也能执行 - 网络请求使用异步变体(处理中止/取消)
- React Hook 会自动清理——无需手动拆除
- 使用
setOptions动态重新配置(例如,为高级用户缩短等待时间) - 组合使用工具处理复杂场景(速率受限的队列)
- 在 RateLimiter 上使用
onReject,在用户触发速率限制时通知他们
常见问题
- 需要节流时却使用了防抖(防抖会等待活动停止,节流则保证定期执行)
- 处理长时间持续事件时,防抖没有使用
maxWait - 每次渲染都创建新实例(请使用 Hook 或模块级实例)
- 在非 React 环境中忘记清理(调用
cancel())
评论
支持 Markdown