diff --git a/docs/ar/framework/react/reference/functions/useasyncratelimiter.md b/docs/ar/framework/react/reference/functions/useasyncratelimiter.md index a6943c047..b822c1d3d 100644 --- a/docs/ar/framework/react/reference/functions/useasyncratelimiter.md +++ b/docs/ar/framework/react/reference/functions/useasyncratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:20:00.488Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:02:32.631Z' id: useAsyncRateLimiter title: useAsyncRateLimiter --- @@ -13,7 +13,7 @@ title: useAsyncRateLimiter function useAsyncRateLimiter(fn, options): AsyncRateLimiter ``` -Defined in: [react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts:43](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts#L43) +Defined in: [react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts:54](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts#L54) A low-level React hook that creates an `AsyncRateLimiter` instance to limit how many times an async function can execute within a time window. @@ -24,6 +24,16 @@ Rate limiting allows an async function to execute up to a specified limit within then blocks subsequent calls until the window passes. This is useful for respecting API rate limits, managing resource constraints, or controlling bursts of async operations. +Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + ## Type Parameters • **TFn** *extends* `AnyAsyncFunction` @@ -45,21 +55,22 @@ managing resource constraints, or controlling bursts of async operations. ## Example ```tsx -// Basic API call rate limiting +// Basic API call rate limiting with return value const { maybeExecute } = useAsyncRateLimiter( async (id: string) => { const data = await api.fetchData(id); - return data; + return data; // Return value is preserved }, { limit: 5, window: 1000 } // 5 calls per second ); -// With state management +// With state management and return value const [data, setData] = useState(null); const { maybeExecute } = useAsyncRateLimiter( async (query) => { const result = await searchAPI(query); setData(result); + return result; // Return value can be used by the caller }, { limit: 10, diff --git a/docs/ar/framework/react/reference/functions/useratelimitedcallback.md b/docs/ar/framework/react/reference/functions/useratelimitedcallback.md index 9ebd5ea10..c29aefd95 100644 --- a/docs/ar/framework/react/reference/functions/useratelimitedcallback.md +++ b/docs/ar/framework/react/reference/functions/useratelimitedcallback.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-04-24T02:14:56.000Z' -translation-updated-at: '2025-05-06T20:44:41.598Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:02:32.627Z' id: useRateLimitedCallback title: useRateLimitedCallback --- @@ -13,7 +13,7 @@ title: useRateLimitedCallback function useRateLimitedCallback(fn, options): (...args) => boolean ``` -Defined in: [rate-limiter/useRateLimitedCallback.ts:52](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedCallback.ts#L52) +Defined in: [react-pacer/src/rate-limiter/useRateLimitedCallback.ts:59](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedCallback.ts#L59) A React hook that creates a rate-limited version of a callback function. This hook is essentially a wrapper around the basic `rateLimiter` function @@ -26,6 +26,12 @@ or debouncing, it does not attempt to space out or intelligently collapse calls. This can lead to bursts of rapid executions followed by periods where all calls are blocked. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns, consider: - useThrottledCallback: When you want consistent spacing between executions (e.g. UI updates) - useDebouncedCallback: When you want to collapse rapid calls into a single execution (e.g. search input) @@ -57,7 +63,7 @@ Consider using the `useRateLimiter` hook instead. ### options -`RateLimiterOptions`\<`TFn`, `TArgs`\> +`RateLimiterOptions`\<`TFn`\> ## Returns @@ -76,7 +82,7 @@ Consider using the `useRateLimiter` hook instead. ## Example ```tsx -// Rate limit API calls to maximum 5 calls per minute +// Rate limit API calls to maximum 5 calls per minute with a sliding window const makeApiCall = useRateLimitedCallback( (data: ApiData) => { return fetch('/api/endpoint', { method: 'POST', body: JSON.stringify(data) }); @@ -84,6 +90,7 @@ const makeApiCall = useRateLimitedCallback( { limit: 5, window: 60000, // 1 minute + windowType: 'sliding', onReject: () => { console.warn('API rate limit reached. Please wait before trying again.'); } diff --git a/docs/ar/framework/react/reference/functions/useratelimitedstate.md b/docs/ar/framework/react/reference/functions/useratelimitedstate.md index 9b3e66c52..e31bea2ff 100644 --- a/docs/ar/framework/react/reference/functions/useratelimitedstate.md +++ b/docs/ar/framework/react/reference/functions/useratelimitedstate.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:20:00.451Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:02:32.623Z' id: useRateLimitedState title: useRateLimitedState --- @@ -13,7 +13,7 @@ title: useRateLimitedState function useRateLimitedState(value, options): [TValue, Dispatch>, RateLimiter>>] ``` -Defined in: [react-pacer/src/rate-limiter/useRateLimitedState.ts:59](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedState.ts#L59) +Defined in: [react-pacer/src/rate-limiter/useRateLimitedState.ts:66](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedState.ts#L66) A React hook that creates a rate-limited state value that enforces a hard limit on state updates within a time window. This hook combines React's useState with rate limiting functionality to provide controlled state updates. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - useThrottledState: When you want consistent spacing between updates (e.g. UI changes) - useDebouncedState: When you want to collapse rapid updates into a single update (e.g. search input) @@ -57,16 +63,18 @@ consider using the lower-level useRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update state at most 5 times per minute +// Basic rate limiting - update state at most 5 times per minute with a sliding window const [value, setValue, rateLimiter] = useRateLimitedState(0, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); -// With rejection callback +// With rejection callback and fixed window const [value, setValue] = useRateLimitedState(0, { limit: 3, window: 5000, + windowType: 'fixed', onReject: (rateLimiter) => { alert(`Rate limit reached. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/ar/framework/react/reference/functions/useratelimitedvalue.md b/docs/ar/framework/react/reference/functions/useratelimitedvalue.md index eb1a15b32..0cbf4e84b 100644 --- a/docs/ar/framework/react/reference/functions/useratelimitedvalue.md +++ b/docs/ar/framework/react/reference/functions/useratelimitedvalue.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:20:00.446Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:02:32.619Z' id: useRateLimitedValue title: useRateLimitedValue --- @@ -13,7 +13,7 @@ title: useRateLimitedValue function useRateLimitedValue(value, options): [TValue, RateLimiter>>] ``` -Defined in: [react-pacer/src/rate-limiter/useRateLimitedValue.ts:47](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedValue.ts#L47) +Defined in: [react-pacer/src/rate-limiter/useRateLimitedValue.ts:55](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedValue.ts#L55) A high-level React hook that creates a rate-limited version of a value that updates at most a certain number of times within a time window. This hook uses React's useState internally to manage the rate-limited state. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - useThrottledValue: When you want consistent spacing between updates (e.g. UI changes) - useDebouncedValue: When you want to collapse rapid updates into a single update (e.g. search input) @@ -56,16 +62,18 @@ consider using the lower-level useRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update at most 5 times per minute +// Basic rate limiting - update at most 5 times per minute with a sliding window const [rateLimitedValue, rateLimiter] = useRateLimitedValue(rawValue, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); -// With rejection callback +// With rejection callback and fixed window const [rateLimitedValue, rateLimiter] = useRateLimitedValue(rawValue, { limit: 3, window: 5000, + windowType: 'fixed', onReject: (rateLimiter) => { console.log(`Update rejected. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/ar/framework/react/reference/functions/useratelimiter.md b/docs/ar/framework/react/reference/functions/useratelimiter.md index 5b6c2657a..5a743c4fd 100644 --- a/docs/ar/framework/react/reference/functions/useratelimiter.md +++ b/docs/ar/framework/react/reference/functions/useratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:20:00.442Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:02:32.615Z' id: useRateLimiter title: useRateLimiter --- @@ -13,7 +13,7 @@ title: useRateLimiter function useRateLimiter(fn, options): RateLimiter ``` -Defined in: [react-pacer/src/rate-limiter/useRateLimiter.ts:48](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimiter.ts#L48) +Defined in: [react-pacer/src/rate-limiter/useRateLimiter.ts:55](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimiter.ts#L55) A low-level React hook that creates a `RateLimiter` instance to enforce rate limits on function execution. @@ -24,6 +24,12 @@ Rate limiting is a simple "hard limit" approach that allows executions until a m a time window, then blocks all subsequent calls until the window resets. Unlike throttling or debouncing, it does not attempt to space out or collapse executions intelligently. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns: - Use throttling when you want consistent spacing between executions (e.g. UI updates) - Use debouncing when you want to collapse rapid-fire events (e.g. search input) @@ -57,10 +63,11 @@ The hook returns an object containing: ## Example ```tsx -// Basic rate limiting - max 5 calls per minute +// Basic rate limiting - max 5 calls per minute with a sliding window const { maybeExecute } = useRateLimiter(apiCall, { limit: 5, window: 60000, + windowType: 'sliding', }); // Monitor rate limit status diff --git a/docs/ar/framework/solid/reference/functions/createasyncratelimiter.md b/docs/ar/framework/solid/reference/functions/createasyncratelimiter.md index d092cd35e..6a6994c5f 100644 --- a/docs/ar/framework/solid/reference/functions/createasyncratelimiter.md +++ b/docs/ar/framework/solid/reference/functions/createasyncratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:20:00.414Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:02:32.609Z' id: createAsyncRateLimiter title: createAsyncRateLimiter --- @@ -13,7 +13,7 @@ title: createAsyncRateLimiter function createAsyncRateLimiter(fn, initialOptions): SolidAsyncRateLimiter ``` -Defined in: [async-rate-limiter/createAsyncRateLimiter.ts:62](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L62) +Defined in: [async-rate-limiter/createAsyncRateLimiter.ts:73](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L73) A low-level Solid hook that creates an `AsyncRateLimiter` instance to limit how many times an async function can execute within a time window. @@ -24,6 +24,16 @@ Rate limiting allows an async function to execute up to a specified limit within then blocks subsequent calls until the window passes. This is useful for respecting API rate limits, managing resource constraints, or controlling bursts of async operations. +Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + ## Type Parameters • **TFn** *extends* `AnyAsyncFunction` @@ -45,21 +55,22 @@ managing resource constraints, or controlling bursts of async operations. ## Example ```tsx -// Basic API call rate limiting +// Basic API call rate limiting with return value const { maybeExecute } = createAsyncRateLimiter( async (id: string) => { const data = await api.fetchData(id); - return data; + return data; // Return value is preserved }, { limit: 5, window: 1000 } // 5 calls per second ); -// With state management +// With state management and return value const [data, setData] = createSignal(null); const { maybeExecute } = createAsyncRateLimiter( async (query) => { const result = await searchAPI(query); setData(result); + return result; // Return value can be used by the caller }, { limit: 10, diff --git a/docs/ar/framework/solid/reference/functions/createratelimitedsignal.md b/docs/ar/framework/solid/reference/functions/createratelimitedsignal.md index 28236b6b6..f5b564728 100644 --- a/docs/ar/framework/solid/reference/functions/createratelimitedsignal.md +++ b/docs/ar/framework/solid/reference/functions/createratelimitedsignal.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:20:00.389Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:02:32.606Z' id: createRateLimitedSignal title: createRateLimitedSignal --- @@ -13,7 +13,7 @@ title: createRateLimitedSignal function createRateLimitedSignal(value, initialOptions): [Accessor, Setter, SolidRateLimiter>] ``` -Defined in: [rate-limiter/createRateLimitedSignal.ts:57](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedSignal.ts#L57) +Defined in: [rate-limiter/createRateLimitedSignal.ts:65](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedSignal.ts#L65) A Solid hook that creates a rate-limited state value that enforces a hard limit on state updates within a time window. This hook combines Solid's createSignal with rate limiting functionality to provide controlled state updates. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - createThrottledSignal: When you want consistent spacing between updates (e.g. UI changes) - createDebouncedSignal: When you want to collapse rapid updates into a single update (e.g. search input) @@ -57,16 +63,18 @@ consider using the lower-level createRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update state at most 5 times per minute +// Basic rate limiting - update state at most 5 times per minute with a sliding window const [value, setValue, rateLimiter] = createRateLimitedSignal(0, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); -// With rejection callback +// With rejection callback and fixed window const [value, setValue] = createRateLimitedSignal(0, { limit: 3, window: 5000, + windowType: 'fixed', onReject: (rateLimiter) => { alert(`Rate limit reached. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/ar/framework/solid/reference/functions/createratelimitedvalue.md b/docs/ar/framework/solid/reference/functions/createratelimitedvalue.md index 6fd4ced62..2599ce1a1 100644 --- a/docs/ar/framework/solid/reference/functions/createratelimitedvalue.md +++ b/docs/ar/framework/solid/reference/functions/createratelimitedvalue.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:20:00.384Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:02:32.602Z' id: createRateLimitedValue title: createRateLimitedValue --- @@ -13,7 +13,7 @@ title: createRateLimitedValue function createRateLimitedValue(value, initialOptions): [Accessor, SolidRateLimiter>] ``` -Defined in: [rate-limiter/createRateLimitedValue.ts:43](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedValue.ts#L43) +Defined in: [rate-limiter/createRateLimitedValue.ts:50](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedValue.ts#L50) A high-level Solid hook that creates a rate-limited version of a value that updates at most a certain number of times within a time window. This hook uses Solid's createSignal internally to manage the rate-limited state. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - createThrottledValue: When you want consistent spacing between updates (e.g. UI changes) - createDebouncedValue: When you want to collapse rapid updates into a single update (e.g. search input) @@ -56,10 +62,11 @@ consider using the lower-level createRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update at most 5 times per minute +// Basic rate limiting - update at most 5 times per minute with a sliding window const [rateLimitedValue, rateLimiter] = createRateLimitedValue(rawValue, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); // Use the rate-limited value diff --git a/docs/ar/framework/solid/reference/functions/createratelimiter.md b/docs/ar/framework/solid/reference/functions/createratelimiter.md index 90a9dc86b..556792bd1 100644 --- a/docs/ar/framework/solid/reference/functions/createratelimiter.md +++ b/docs/ar/framework/solid/reference/functions/createratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:20:00.380Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:02:32.598Z' id: createRateLimiter title: createRateLimiter --- @@ -13,7 +13,7 @@ title: createRateLimiter function createRateLimiter(fn, initialOptions): SolidRateLimiter ``` -Defined in: [rate-limiter/createRateLimiter.ts:61](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts#L61) +Defined in: [rate-limiter/createRateLimiter.ts:68](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts#L68) A low-level Solid hook that creates a `RateLimiter` instance to enforce rate limits on function execution. @@ -24,6 +24,12 @@ Rate limiting is a simple "hard limit" approach that allows executions until a m a time window, then blocks all subsequent calls until the window resets. Unlike throttling or debouncing, it does not attempt to space out or collapse executions intelligently. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns: - Use throttling when you want consistent spacing between executions (e.g. UI updates) - Use debouncing when you want to collapse rapid-fire events (e.g. search input) @@ -50,10 +56,11 @@ For smoother execution patterns: ## Example ```tsx -// Basic rate limiting - max 5 calls per minute +// Basic rate limiting - max 5 calls per minute with a sliding window const rateLimiter = createRateLimiter(apiCall, { limit: 5, window: 60000, + windowType: 'sliding' }); // Monitor rate limit status diff --git a/docs/ar/guides/debouncing.md b/docs/ar/guides/debouncing.md index 80e1e532c..787b69633 100644 --- a/docs/ar/guides/debouncing.md +++ b/docs/ar/guides/debouncing.md @@ -1,23 +1,23 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:22:36.023Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:05:27.197Z' title: دليل التخلص من الارتداد (Debouncing) id: debouncing --- -# دليل التخميد (Debouncing) +# دليل إزالة الارتداد (Debouncing) -تعتبر تقنيات تحديد المعدل (Rate Limiting)، التخميد (Throttling)، والتخميد (Debouncing) ثلاث طرق مختلفة للتحكم في تكرار تنفيذ الدوال. كل تقنية تمنع عمليات التنفيذ بشكل مختلف، مما يجعلها "فاقدة" (lossy) - أي أن بعض استدعاءات الدوال لن تنفذ عند طلب تشغيلها بشكل متكرر جدًا. فهم الوقت المناسب لاستخدام كل نهج أمر بالغ الأهمية لبناء تطبيقات عالية الأداء وموثوقة. سيغطي هذا الدليل مفاهيم التخميد (Debouncing) في TanStack Pacer. +تعتبر تقنيات تحديد المعدل (Rate Limiting)، والتحكم في التدفق (Throttling)، وإزالة الارتداد (Debouncing) ثلاث طرق مختلفة للتحكم في تكرار تنفيذ الدوال. كل تقنية تمنع عمليات التنفيذ بشكل مختلف، مما يجعلها "فاقدة" - أي أن بعض استدعاءات الدوال لن يتم تنفيذها عند طلب تشغيلها بشكل متكرر جدًا. فهم متى تستخدم كل تقنية أمر بالغ الأهمية لبناء تطبيقات عالية الأداء وموثوقة. سيغطي هذا الدليل مفاهيم إزالة الارتداد (Debouncing) في TanStack Pacer. -## مفهوم التخميد (Debouncing) +## مفهوم إزالة الارتداد (Debouncing) -التخميد (Debouncing) هو تقنية تؤخر تنفيذ الدالة حتى مرور فترة محددة من عدم النشاط. على عكس تحديد المعدل (Rate Limiting) الذي يسمح باندفاعات من عمليات التنفيذ حتى حد معين، أو التخميد (Throttling) الذي يضمن تنفيذًا متباعدًا بشكل متساوٍ، فإن التخميد (Debouncing) يدمج عدة استدعاءات سريعة للدالة في تنفيذ واحد يحدث فقط بعد توقف الاستدعاءات. هذا يجعل التخميد (Debouncing) مثاليًا للتعامل مع اندفاعات الأحداث حيث تهتم فقط بالحالة النهائية بعد استقرار النشاط. +إزالة الارتداد (Debouncing) هي تقنية تؤخر تنفيذ الدالة حتى مرور فترة محددة من عدم النشاط. على عكس تحديد المعدل (Rate Limiting) الذي يسمح بتنفيذ دفعات من الاستدعاءات حتى حد معين، أو التحكم في التدفق (Throttling) الذي يضمن تنفيذًا متباعدًا بشكل متساوٍ، فإن إزالة الارتداد (Debouncing) تجمع استدعاءات الدالة المتعددة السريعة في تنفيذ واحد يحدث فقط بعد توقف الاستدعاءات. هذا يجعل إزالة الارتداد (Debouncing) مثالية للتعامل مع دفعات الأحداث حيث تهتم فقط بالحالة النهائية بعد استقرار النشاط. -### تصور التخميد (Debouncing) +### تصور إزالة الارتداد (Debouncing) ```text Debouncing (wait: 3 ticks) Timeline: [1 second per tick] -Calls: � ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ +Calls: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ Executed: ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ⏳ -> ✅ ❌ ⏳ -> ✅ [=================================================================] ^ Executes here after @@ -27,9 +27,9 @@ Executed: ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ⏳ -> ✅ ❌ No execution Resets timer [Delayed Execute] [Wait] [Delayed Execute] ``` -### متى تستخدم التخميد (Debouncing) +### متى تستخدم إزالة الارتداد (Debouncing) -التخميد (Debouncing) فعال بشكل خاص عندما تريد الانتظار حتى "توقف" النشاط قبل اتخاذ إجراء. هذا يجعله مثاليًا للتعامل مع مدخلات المستخدم أو الأحداث الأخرى التي يتم تشغيلها بسرعة حيث تهتم فقط بالحالة النهائية. +تكون إزالة الارتداد (Debouncing) فعالة بشكل خاص عندما تريد الانتظار حتى "توقف" النشاط قبل اتخاذ إجراء. هذا يجعلها مثالية للتعامل مع إدخال المستخدم أو الأحداث الأخرى التي يتم تشغيلها بسرعة حيث تهتم فقط بالحالة النهائية. من حالات الاستخدام الشائعة: - حقول إدخال البحث حيث تريد الانتظار حتى ينتهي المستخدم من الكتابة @@ -39,24 +39,24 @@ Executed: ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ⏳ -> ✅ ❌ - استدعاءات API التي يجب أن تحدث فقط بعد استقرار نشاط المستخدم - أي سيناريو حيث تهتم فقط بالقيمة النهائية بعد التغييرات السريعة -### متى لا تستخدم التخميد (Debouncing) +### متى لا تستخدم إزالة الارتداد (Debouncing) -قد لا يكون التخميد (Debouncing) هو الخيار الأفضل عندما: -- تحتاج إلى تنفيذ مضمون خلال فترة زمنية محددة (استخدم [التخميد (Throttling)](../guides/throttling) بدلاً من ذلك) -- لا يمكنك تحمل فقدان أي عمليات تنفيذ (استخدم [الانتظار في قائمة (Queueing)](../guides/queueing) بدلاً من ذلك) +قد لا تكون إزالة الارتداد (Debouncing) هي الخيار الأفضل عندما: +- تحتاج إلى تنفيذ مضمون خلال فترة زمنية محددة (استخدم [التحكم في التدفق (Throttling)](../guides/throttling) بدلاً من ذلك) +- لا يمكنك تحمل فقدان أي عمليات تنفيذ (استخدم [الطابور (Queueing)](../guides/queueing) بدلاً من ذلك) -## التخميد (Debouncing) في TanStack Pacer +## إزالة الارتداد (Debouncing) في TanStack Pacer -يوفر TanStack Pacer كلاً من التخميد المتزامن وغير المتزامن من خلال فئتي `Debouncer` و `AsyncDebouncer` على التوالي (ووظائفهما المقابلة `debounce` و `asyncDebounce`). +يوفر TanStack Pacer إزالة الارتداد (Debouncing) المتزامن وغير المتزامن من خلال فئتي `Debouncer` و `AsyncDebouncer` على التوالي (ووظائفهما المقابلة `debounce` و `asyncDebounce`). ### الاستخدام الأساسي مع `debounce` -تعتبر دالة `debounce` أبسط طريقة لإضافة التخميد (Debouncing) إلى أي دالة: +تعتبر الدالة `debounce` أبسط طريقة لإضافة إزالة الارتداد (Debouncing) إلى أي دالة: ```ts import { debounce } from '@tanstack/pacer' -// تخميد إدخال البحث للانتظار حتى يتوقف المستخدم عن الكتابة +// إزالة الارتداد (Debouncing) لإدخال البحث للانتظار حتى يتوقف المستخدم عن الكتابة const debouncedSearch = debounce( (searchTerm: string) => performSearch(searchTerm), { @@ -71,7 +71,7 @@ searchInput.addEventListener('input', (e) => { ### الاستخدام المتقدم مع فئة `Debouncer` -لمزيد من التحكم في سلوك التخميد (Debouncing)، يمكنك استخدام فئة `Debouncer` مباشرة: +لمزيد من التحكم في سلوك إزالة الارتداد (Debouncing)، يمكنك استخدام فئة `Debouncer` مباشرة: ```ts import { Debouncer } from '@tanstack/pacer' @@ -94,7 +94,7 @@ searchDebouncer.cancel() ### التنفيذ الأولي والنهائي -يدعم المخمد المتزامن كلاً من عمليات التنفيذ على الحافة الأولية والنهائية: +يدعم مزيل الارتداد (Debouncer) المتزامن عمليات التنفيذ على الحافة الأولية والنهائية: ```ts const debouncedFn = debounce(fn, { @@ -116,28 +116,28 @@ const debouncedFn = debounce(fn, { ### وقت الانتظار الأقصى -لا يحتوي مخمد TanStack Pacer عن قصد على خيار `maxWait` مثل مكتبات التخميد (Debouncing) الأخرى. إذا كنت بحاجة إلى السماح بتنفيذ عمليات على فترة زمنية أكثر تباعدًا، ففكر في استخدام تقنية [التخميد (Throttling)](../guides/throttling) بدلاً من ذلك. +لا يحتوي مزيل الارتداد (Debouncer) في TanStack Pacer عمدًا على خيار `maxWait` مثل مكتبات إزالة الارتداد (Debouncing) الأخرى. إذا كنت بحاجة إلى السماح بتنفيذ عمليات على فترة زمنية أكثر انتشارًا، ففكر في استخدام تقنية [التحكم في التدفق (Throttling)](../guides/throttling) بدلاً من ذلك. ### التمكين/التعطيل -تدعم فئة `Debouncer` التمكين/التعطيل عبر خيار `enabled`. باستخدام طريقة `setOptions`، يمكنك تمكين/تعطيل المخمد في أي وقت: +تدعم فئة `Debouncer` التمكين/التعطيل عبر خيار `enabled`. باستخدام طريقة `setOptions`، يمكنك تمكين/تعطيل مزيل الارتداد (Debouncer) في أي وقت: ```ts const debouncer = new Debouncer(fn, { wait: 500, enabled: false }) // التعطيل افتراضيًا debouncer.setOptions({ enabled: true }) // التمكين في أي وقت ``` -إذا كنت تستخدم محول إطار عمل حيث تكون خيارات المخمد تفاعلية، يمكنك تعيين خيار `enabled` إلى قيمة شرطية لتمكين/تعطيل المخمد على الفور: +إذا كنت تستخدم محول إطار عمل حيث تكون خيارات مزيل الارتداد (Debouncer) تفاعلية، يمكنك تعيين خيار `enabled` إلى قيمة شرطية لتمكين/تعطيل مزيل الارتداد (Debouncer) على الفور: ```ts // مثال React const debouncer = useDebouncer( setSearch, - { wait: 500, enabled: searchInput.value.length > 3 } // تمكين/تعطيل بناءً على طول الإدخال إذا كنت تستخدم محول إطار عمل يدعم الخيارات التفاعلية + { wait: 500, enabled: searchInput.value.length > 3 } // تمكين/تعطيل بناءً على طول الإدخال IF باستخدام محول إطار عمل يدعم الخيارات التفاعلية ) ``` -ومع ذلك، إذا كنت تستخدم دالة `debounce` أو فئة `Debouncer` مباشرة، فيجب عليك استخدام طريقة `setOptions` لتغيير خيار `enabled`، حيث أن الخيارات التي يتم تمريرها يتم تمريرها بالفعل إلى منشئ فئة `Debouncer`. +ومع ذلك، إذا كنت تستخدم الدالة `debounce` أو فئة `Debouncer` مباشرة، فيجب عليك استخدام طريقة `setOptions` لتغيير خيار `enabled`، حيث أن الخيارات التي يتم تمريرها يتم تمريرها بالفعل إلى مُنشئ فئة `Debouncer`. ```ts // مثال Solid @@ -147,13 +147,13 @@ createEffect(() => { }) ``` -### خيارات رد الاتصال +### خيارات ردود النداء -يدعم كل من المخمد المتزامن وغير المتزامن خيارات رد الاتصال للتعامل مع جوانب مختلفة من دورة حياة التخميد (Debouncing): +يدعم كل من مزيل الارتداد (Debouncer) المتزامن وغير المتزامن خيارات ردود النداء للتعامل مع جوانب مختلفة من دورة حياة إزالة الارتداد (Debouncing): -#### ردود الاتصال للمخمد المتزامن +#### ردود نداء مزيل الارتداد (Debouncer) المتزامن -يدعم المخمد المتزامن `Debouncer` رد الاتصال التالي: +يدعم `Debouncer` المتزامن رد النداء التالي: ```ts const debouncer = new Debouncer(fn, { @@ -165,11 +165,11 @@ const debouncer = new Debouncer(fn, { }) ``` -يتم استدعاء رد الاتصال `onExecute` بعد كل تنفيذ ناجح للدالة المخمدة، مما يجعله مفيدًا لتتبع عمليات التنفيذ، تحديث حالة واجهة المستخدم، أو تنفيذ عمليات التنظيف. +يتم استدعاء رد النداء `onExecute` بعد كل تنفيذ ناجح للدالة التي تمت إزالة ارتدادها، مما يجعله مفيدًا لتتبع عمليات التنفيذ، أو تحديث حالة واجهة المستخدم، أو تنفيذ عمليات التنظيف. -#### ردود الاتصال للمخمد غير المتزامن +#### ردود نداء مزيل الارتداد (Debouncer) غير المتزامن -يحتوي المخمد غير المتزامن `AsyncDebouncer` على مجموعة مختلفة من ردود الاتصال مقارنة بالإصدار المتزامن. +يحتوي `AsyncDebouncer` على مجموعة مختلفة من ردود النداء مقارنة بالإصدار المتزامن. ```ts const asyncDebouncer = new AsyncDebouncer(async (value) => { @@ -182,7 +182,7 @@ const asyncDebouncer = new AsyncDebouncer(async (value) => { }, onSettled: (debouncer) => { // يتم استدعاؤه بعد كل محاولة تنفيذ - console.log('استقرت الدالة غير المتزامنة', debouncer.getSettledCount()) + console.log('تم تسوية الدالة غير المتزامنة', debouncer.getSettledCount()) }, onError: (error) => { // يتم استدعاؤه إذا ألقت الدالة غير المتزامنة خطأ @@ -191,37 +191,31 @@ const asyncDebouncer = new AsyncDebouncer(async (value) => { }) ``` -يتم استدعاء رد الاتصال `onSuccess` بعد كل تنفيذ ناجح للدالة المخمدة، بينما يتم استدعاء رد الاتصال `onError` إذا ألقت الدالة غير المتزامنة خطأ. يتم استدعاء رد الاتصال `onSettled` بعد كل محاولة تنفيذ، بغض النظر عن النجاح أو الفشل. تعتبر ردود الاتصال هذه مفيدة بشكل خاص لتتبع عدد عمليات التنفيذ، تحديث حالة واجهة المستخدم، معالجة الأخطاء، تنفيذ عمليات التنظيف، وتسجيل مقاييس التنفيذ. +يتم استدعاء رد النداء `onSuccess` بعد كل تنفيذ ناجح للدالة التي تمت إزالة ارتدادها، بينما يتم استدعاء `onError` إذا ألقت الدالة غير المتزامنة خطأ. يتم استدعاء `onSettled` بعد كل محاولة تنفيذ، بغض النظر عن النجاح أو الفشل. تعتبر ردود النداء هذه مفيدة بشكل خاص لتتبع عدد عمليات التنفيذ، وتحديث حالة واجهة المستخدم، والتعامل مع الأخطاء، وتنفيذ عمليات التنظيف، وتسجيل مقاييس التنفيذ. -### التخميد غير المتزامن (Async Debouncing) +### إزالة الارتداد (Debouncing) غير المتزامنة -يوفر المخمد غير المتزامن طريقة قوية للتعامل مع العمليات غير المتزامنة مع التخميد (Debouncing)، ويقدم عدة مزايا رئيسية مقارنة بالإصدار المتزامن. بينما يكون المخمد المتزامن رائعًا لأحداث واجهة المستخدم والملاحظات الفورية، فإن الإصدار غير المتزامن مصمم خصيصًا للتعامل مع استدعاءات API، عمليات قاعدة البيانات، والمهام غير المتزامنة الأخرى. +يوفر مزيل الارتداد (Debouncer) غير المتزامن طريقة قوية للتعامل مع العمليات غير المتزامنة مع إزالة الارتداد (Debouncing)، حيث يقدم عدة مزايا رئيسية مقارنة بالإصدار المتزامن. بينما يعتبر مزيل الارتداد (Debouncer) المتزامن رائعًا لأحداث واجهة المستخدم والملاحظات الفورية، فإن الإصدار غير المتزامن مصمم خصيصًا للتعامل مع استدعاءات API، وعمليات قاعدة البيانات، والمهام غير المتزامنة الأخرى. -#### الاختلافات الرئيسية عن التخميد المتزامن +#### الاختلافات الرئيسية عن إزالة الارتداد (Debouncing) المتزامنة 1. **معالجة القيمة المرجعة** -على عكس المخمد المتزامن الذي يُرجع void، يسمح الإصدار غير المتزامن لك بالتقاط واستخدام القيمة المرجعة من دالتك المخمدة. هذا مفيد بشكل خاص عندما تحتاج إلى العمل مع نتائج استدعاءات API أو العمليات غير المتزامنة الأخرى. تُرجع طريقة `maybeExecute` وعدًا (Promise) يحل بقيمة إرجاع الدالة، مما يسمح لك بالانتظار للنتائج ومعالجتها بشكل مناسب. +على عكس مزيل الارتداد (Debouncer) المتزامن الذي يُرجع void، يسمح الإصدار غير المتزامن بالتقاط واستخدام القيمة المرجعة من الدالة التي تمت إزالة ارتدادها. هذا مفيد بشكل خاص عندما تحتاج إلى العمل مع نتائج استدعاءات API أو العمليات غير المتزامنة الأخرى. تُرجع طريقة `maybeExecute` وعدًا (Promise) يتم حله بقيمة إرجاع الدالة، مما يسمح لك بالانتظار للنتائج والتعامل معها بشكل مناسب. -2. **نظام رد الاتصال المحسن** -يوفر المخمد غير المتزامن نظام رد اتصال أكثر تطورًا مقارنة برد الاتصال الفردي `onExecute` في الإصدار المتزامن. يتضمن هذا النظام: -- `onSuccess`: يتم استدعاؤه عند اكتمال الدالة غير المتزامنة بنجاح، ويوفر كلًا من النتيجة ومثيل المخمد -- `onError`: يتم استدعاؤه عندما تلقى الدالة غير المتزامنة خطأ، ويوفر كلًا من الخطأ ومثيل المخمد -- `onSettled`: يتم استدعاؤه بعد كل محاولة تنفيذ، بغض النظر عن النجاح أو الفشل +2. **ردود نداء مختلفة** +يدعم `AsyncDebouncer` ردود النداء التالية بدلاً من `onExecute` فقط في الإصدار المتزامن: +- `onSuccess`: يتم استدعاؤه بعد كل تنفيذ ناجح، مع توفير مثيل مزيل الارتداد (Debouncer) +- `onSettled`: يتم استدعاؤه بعد كل تنفيذ، مع توفير مثيل مزيل الارتداد (Debouncer) +- `onError`: يتم استدعاؤه إذا ألقت الدالة غير المتزامنة خطأ، مع توفير كل من الخطأ ومثيل مزيل الارتداد (Debouncer) -3. **تتبع التنفيذ** -يوفر المخمد غير المتزامن تتبعًا شاملًا للتنفيذ من خلال عدة طرق: -- `getSuccessCount()`: عدد عمليات التنفيذ الناجحة -- `getErrorCount()`: عدد عمليات التنفيذ الفاشلة -- `getSettledCount()`: إجمالي عدد عمليات التنفيذ المستقرة (النجاح + الفشل) +3. **التنفيذ المتسلسل** +نظرًا لأن طريقة `maybeExecute` لمزيل الارتداد (Debouncer) تُرجع وعدًا (Promise)، يمكنك اختيار انتظار كل تنفيذ قبل بدء التالي. هذا يمنحك التحكم في ترتيب التنفيذ ويضمن معالجة كل استدعاء لأحدث البيانات. هذا مفيد بشكل خاص عند التعامل مع العمليات التي تعتمد على نتائج الاستدعاءات السابقة أو عندما يكون الحفاظ على اتساق البيانات أمرًا بالغ الأهمية. -4. **التنفيذ المتسلسل** -يضمن المخمد غير المتزامن أن عمليات التنفيذ اللاحقة تنتظر اكتمال الاستدعاء السابق قبل البدء. هذا يمنع التنفيذ خارج الترتيب ويضمن أن كل استدعاء يعالج أحدث البيانات. هذا مهم بشكل خاص عند التعامل مع العمليات التي تعتمد على نتائج الاستدعاءات السابقة أو عندما يكون الحفاظ على تناسق البيانات أمرًا بالغ الأهمية. +على سبيل المثال، إذا كنت تقوم بتحديث ملف تعريف المستخدم ثم تقوم على الفور جلب بياناته المحدثة، يمكنك انتظار عملية التحديث قبل بدء عملية الجلب: -على سبيل المثال، إذا كنت تقوم بتحديث ملف تعريف المستخدم ثم تقوم على الفور جلب بياناته المحدثة، فإن المخمد غير المتزامن سيتأكد من أن عملية الجلب تنتظر اكتمال التحديث، مما يمنع ظروف السباق (race conditions) حيث قد تحصل على بيانات قديمة. +#### مثال الاستخدام الأساسي -#### مثال على الاستخدام الأساسي - -إليك مثالًا أساسيًا يوضح كيفية استخدام المخمد غير المتزامن لعملية بحث: +إليك مثالاً أساسيًا يوضح كيفية استخدام مزيل الارتداد (Debouncer) غير المتزامن لعملية بحث: ```ts const debouncedSearch = asyncDebounce( @@ -232,7 +226,7 @@ const debouncedSearch = asyncDebounce( { wait: 500, onSuccess: (results, debouncer) => { - console.log('نجاح البحث:', results) + console.log('نجح البحث:', results) }, onError: (error, debouncer) => { console.error('فشل البحث:', error) @@ -244,22 +238,9 @@ const debouncedSearch = asyncDebounce( const results = await debouncedSearch('query') ``` -#### أنماط متقدمة - -يمكن دمج المخمد غير المتزامن مع أنماط مختلفة لحل المشكلات المعقدة: - -1. **تكامل إدارة الحالة** -عند استخدام المخمد غير المتزامن مع أنظمة إدارة الحالة (مثل useState في React أو createSignal في Solid)، يمكنك إنشاء أنماط قوية للتعامل مع حالات التحميل، حالات الخطأ، وتحديثات البيانات. توفر ردود اتصال المخمد خطاطيف مثالية لتحديث حالة واجهة المستخدم بناءً على نجاح أو فشل العمليات. - -2. **منع ظروف السباق (Race Conditions)** -يمنع نمط التحور ذو الرحلة الواحدة (single-flight mutation) ظروف السباق في العديد من السيناريوهات. عندما تحاول أجزاء متعددة من تطبيقك تحديث نفس المورد في نفس الوقت، يضمن المخمد أن أحدث تحديث فقط هو الذي يحدث فعليًا، مع توفير النتائج لجميع المتصلين. - -3. **استعادة الخطأ** -تجعل قدرات معالجة الأخطاء للمخمد غير المتزامن منه مثاليًا لتنفيذ منطق إعادة المحاولة وأنماط استعادة الخطأ. يمكنك استخدام رد الاتصال `onError` لتنفيذ استراتيجيات معالجة أخطاء مخصصة، مثل التراجع الأسي (exponential backoff) أو آليات الاحتياطي. - -### محولات الأطر (Framework Adapters) +### محولات الأطر -يوفر كل محول إطار خطاطيف تبني على وظيفة التخميد الأساسية للتكامل مع نظام إدارة الحالة الخاص بالإطار. تتوفر خطاطيف مثل `createDebouncer`، `useDebouncedCallback`، `useDebouncedState`، أو `useDebouncedValue` لكل إطار. +يوفر كل محول إطار خطافات (hooks) تعتمد على وظائف إزالة الارتداد (Debouncing) الأساسية للاندماج مع نظام إدارة الحالة الخاص بالإطار. تتوفر خطافات مثل `createDebouncer`، و `useDebouncedCallback`، و `useDebouncedState`، أو `useDebouncedValue` لكل إطار. إليك بعض الأمثلة: @@ -274,7 +255,7 @@ const debouncer = useDebouncer( { wait: 500 } ) -// خطاف رد اتصال بسيط لحالات الاستخدام الأساسية +// خطاف رد نداء بسيط لحالات الاستخدام الأساسية const handleSearch = useDebouncedCallback( (query: string) => fetchSearchResults(query), { wait: 500 } @@ -282,4 +263,28 @@ const handleSearch = useDebouncedCallback( // خطاف قائم على الحالة لإدارة الحالة التفاعلية const [instantState, setInstantState] = useState('') -const [debouncedValue] = useDebounced +const [debouncedValue] = useDebouncedValue( + instantState, // القيمة المراد إزالة ارتدادها + { wait: 500 } +) +``` + +#### Solid + +```tsx +import { createDebouncer, createDebouncedSignal } from '@tanstack/solid-pacer' + +// خطاف منخفض المستوى للتحكم الكامل +const debouncer = createDebouncer( + (value: string) => saveToDatabase(value), + { wait: 500 } +) + +// خطاف إشارة (Signal) لإدارة الحالة +const [searchTerm, setSearchTerm, debouncer] = createDebouncedSignal('', { + wait: 500, + onExecute: (debouncer) => { + console.log('إجمالي عمليات التنفيذ:', debouncer.getExecutionCount()) + } +}) +``` diff --git a/docs/ar/guides/rate-limiting.md b/docs/ar/guides/rate-limiting.md index cb01c0136..d78105b5f 100644 --- a/docs/ar/guides/rate-limiting.md +++ b/docs/ar/guides/rate-limiting.md @@ -1,68 +1,98 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:22:37.193Z' -title: ديل تحديد المعدل (Rate Limiting) +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:05:32.754Z' +title: دليل تحديد المعدل (Rate Limiting) id: rate-limiting --- -# دليل تحديد معدل التنفيذ (Rate Limiting) +# دليل التحديد المسبق لمعدل التنفيذ (Rate Limiting) -تعد تقنيات تحديد معدل التنفيذ (Rate Limiting)، والتحكم في التردد (Throttling)، وإلغاء الاهتزاز (Debouncing) ثلاث طرق مختلفة للتحكم في تكرار تنفيذ الدوال. كل تقنية تمنع عمليات التنفيذ بطريقة مختلفة، مما يجعلها "فاقدة" (lossy) - أي أن بعض استدعاءات الدوال لن تنفذ عند طلب تشغيلها بشكل متكرر جدًا. يعد فهم الوقت المناسب لاستخدام كل تقنية أمرًا بالغ الأهمية لبناء تطبيقات عالية الأداء وموثوقة. سيغطي هذا الدليل مفاهيم تحديد معدل التنفيذ في TanStack Pacer. +تعد تقنيات **التحديد المسبق لمعدل التنفيذ (Rate Limiting)** و**التحكم في معدل التنفيذ (Throttling)** و**إلغاء الاهتزاز (Debouncing)** ثلاث طرق مختلفة للتحكم في معدل تنفيذ الدوال. كل تقنية تمنع عمليات التنفيذ بطريقة مختلفة، مما يجعلها "فاقدة" (lossy) - أي أن بعض استدعاءات الدوال لن تنفذ عند طلب تشغيلها بشكل متكرر جدًا. يعد فهم الوقت المناسب لاستخدام كل نهج أمرًا بالغ الأهمية لبناء تطبيقات عالية الأداء وموثوقة. سيغطي هذا الدليل مفاهيم التحديد المسبق لمعدل التنفيذ في TanStack Pacer. > [!ملاحظة] -> TanStack Pacer حاليًا مكتبة للواجهة الأمامية فقط. هذه أدوات لتحديد معدل التنفيذ من جانب العميل. +> TanStack Pacer حاليًا مكتبة للواجهة الأمامية فقط. هذه أدوات للتحديد المسبق لمعدل التنفيذ من جانب العميل. -## مفهوم تحديد معدل التنفيذ (Rate Limiting) +## مفهوم التحديد المسبق لمعدل التنفيذ -تحديد معدل التنفيذ (Rate Limiting) هو تقنية تحد من المعدل الذي يمكن للدالة أن تنفذ فيه خلال نافذة زمنية محددة. وهي مفيدة بشكل خاص في السيناريوهات التي تريد فيها منع استدعاء الدالة بشكل متكرر جدًا، مثل عند التعامل مع طلبات واجهة برمجة التطبيقات (API) أو استدعاءات الخدمات الخارجية الأخرى. وهي النهج الأكثر *بساطة*، حيث تسمح بتنفيذ الدوال في دفعات حتى يتم استنفاذ الحصة المحددة. +التحديد المسبق لمعدل التنفيذ (Rate Limiting) هو تقنية تحد من المعدل الذي يمكن به تنفيذ دالة خلال نافذة زمنية محددة. وهي مفيدة بشكل خاص في السيناريوهات التي تريد فيها منع استدعاء دالة بشكل متكرر جدًا، مثل عند التعامل مع طلبات واجهة برمجة التطبيقات (API) أو استدعاءات الخدمات الخارجية الأخرى. وهي النهج الأكثر *بساطة*، حيث يسمح بتنفيذ الدوال في دفعات حتى يتم استنفاذ الحصة المحددة. -### تصور تحديد معدل التنفيذ +### تصور التحديد المسبق لمعدل التنفيذ ```text -تحديد معدل التنفيذ (حد: 3 استدعاءات لكل نافذة) -الخط الزمني: [1 ثانية لكل علامة] - النافذة 1 | النافذة 2 -الاستدعاءات: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ -تم التنفيذ: ✅ ✅ ✅ ❌ ❌ ✅ ✅ - [=== 3 مسموح بها ===][=== محظور حتى تنتهي النافذة ===][=== نافذة جديدة =======] +Rate Limiting (limit: 3 calls per window) +Timeline: [1 second per tick] + Window 1 | Window 2 +Calls: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ +Executed: ✅ ✅ ✅ ❌ ❌ ✅ ✅ + [=== 3 allowed ===][=== blocked until window ends ===][=== new window =======] ``` -### متى تستخدم تحديد معدل التنفيذ +### أنواع النوافذ -يعد تحديد معدل التنفيذ مهمًا بشكل خاص عند التعامل مع عمليات الواجهة الأمامية التي قد تثقل كاهل خدمات الخلفية عن طريق الخطأ أو تسبب مشاكل في الأداء في المتصفح. +يدعم TanStack Pacer نوعين من نوافذ التحديد المسبق لمعدل التنفيذ: + +1. **النافذة الثابتة (Fixed Window)** (الافتراضي) + - نافذة صارمة يتم إعادة تعيينها بعد فترة النافذة + - جميع عمليات التنفيذ داخل النافذة تحسب ضمن الحد + - يتم إعادة تعيين النافذة بالكامل بعد الفترة + - قد يؤدي إلى سلوك متفجر عند حدود النافذة + +2. **النافذة المنزلقة (Sliding Window)** + - نافذة متحركة تسمح بتنفيذ الدوال عند انتهاء صلاحية القديمة + - توفر معدل تنفيذ أكثر اتساقًا بمرور الوقت + - أفضل للحفاظ على تدفق ثابت من عمليات التنفيذ + - يمنع السلوك المتفجر عند حدود النافذة + +إليك تصورًا للتحديد المسبق لمعدل التنفيذ بنافذة منزلقة: + +```text +Sliding Window Rate Limiting (limit: 3 calls per window) +Timeline: [1 second per tick] + Window 1 | Window 2 +Calls: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ +Executed: ✅ ✅ ✅ ❌ ✅ ✅ ✅ + [=== 3 allowed ===][=== oldest expires, new allowed ===][=== continues sliding =======] +``` + +الفرق الرئيسي هو أنه مع النافذة المنزلقة، بمجرد انتهاء صلاحية أقدم عملية تنفيذ، يُسمح بتنفيذ جديد. وهذا يخلق تدفقًا أكثر اتساقًا من عمليات التنفيذ مقارنة بنهج النافذة الثابتة. + +### متى تستخدم التحديد المسبق لمعدل التنفيذ + +يعد التحديد المسبق لمعدل التنفيذ مهمًا بشكل خاص عند التعامل مع عمليات الواجهة الأمامية التي يمكن أن تطغى عن طريق الخطأ على خدمات الخلفية أو تسبب مشاكل في الأداء في المتصفح. من حالات الاستخدام الشائعة: -- منع إرسال طلبات واجهة برمجة التطبيقات (API) بشكل متكرر عن طريق الخطأ من تفاعلات المستخدم السريعة (مثل النقر على الأزرار أو إرسال النماذج) -- السيناريوهات التي يكون فيها السلوك الدفعي مقبولاً ولكنك تريد تحديد الحد الأقصى للمعدل -- الحماية من الحلقات اللانهائية أو العمليات التكرارية عن طريق الخطأ +- منع البريد المزعج العرضي لواجهة برمجة التطبيقات (API) من تفاعلات المستخدم السريعة (مثل النقر على الأزرار أو إرسال النماذج) +- السيناريوهات التي يكون فيها السلوك المتفجر مقبولًا ولكنك تريد تحديد الحد الأقصى للمعدل +- الحماية من الحلقات اللانهائية العرضية أو العمليات المتكررة -### متى لا تستخدم تحديد معدل التنفيذ +### متى لا تستخدم التحديد المسبق لمعدل التنفيذ -يعد تحديد معدل التنفيذ النهج الأكثر بساطة للتحكم في تكرار تنفيذ الدوال. وهو الأقل مرونة والأكثر تقييدًا بين التقنيات الثلاث. فكر في استخدام [التحكم في التردد (Throttling)](../guides/throttling) أو [إلغاء الاهتزاز (Debouncing)](../guides/debouncing) بدلاً من ذلك للحصول على تنفيذ أكثر تباعدًا. +يعد التحديد المسبق لمعدل التنفيذ النهج الأكثر بساطة للتحكم في معدل تنفيذ الدوال. وهو الأقل مرونة والأكثر تقييدًا من بين التقنيات الثلاث. فكر في استخدام [التحكم في معدل التنفيذ (Throttling)](../guides/throttling) أو [إلغاء الاهتزاز (Debouncing)](../guides/debouncing) بدلاً من ذلك للحصول على عمليات تنفيذ أكثر تباعدًا. > [!تلميح] -> على الأرج لا تريد استخدام "تحديد معدل التنفيذ" لمعظم حالات الاستخدام. فكر في استخدام [التحكم في التردد (Throttling)](../guides/throttling) أو [إلغاء الاهتزاز (Debouncing)](../guides/debouncing) بدلاً من ذلك. +> على الأرجح لا تريد استخدام "التحديد المسبق لمعدل التنفيذ" لمعظم حالات الاستخدام. فكر في استخدام [التحكم في معدل التنفيذ (Throttling)](../guides/throttling) أو [إلغاء الاهتزاز (Debouncing)](../guides/debouncing) بدلاً من ذلك. -طبيعة تحديد معدل التنفيذ "الفاقدة" تعني أيضًا أن بعض عمليات التنفيذ سيتم رفضها وفقدانها. يمكن أن يكون هذا مشكلة إذا كنت بحاجة إلى التأكد من نجاح جميع عمليات التنفيذ دائمًا. فكر في استخدام [الطابور (Queueing)](../guides/queueing) إذا كنت بحاجة إلى التأكد من وضع جميع عمليات التنفيذ في طابور للتنفيذ، ولكن مع تأخير للتحكم في التردد لإبطاء معدل التنفيذ. +طبيعة التحديد المسبق لمعدل التنفيذ "الفاقدة" تعني أيضًا أن بعض عمليات التنفيذ سيتم رفضها وفقدانها. يمكن أن يكون هذا مشكلة إذا كنت بحاجة إلى التأكد من أن جميع عمليات التنفيذ ناجحة دائمًا. فكر في استخدام [الانتظار في قائمة (Queueing)](../guides/queueing) إذا كنت بحاجة إلى التأكد من أن جميع عمليات التنفيذ في قائمة انتظار للتنفيذ، ولكن مع تأخير مقيّد لإبطاء معدل التنفيذ. -## تحديد معدل التنفيذ في TanStack Pacer +## التحديد المسبق لمعدل التنفيذ في TanStack Pacer -يوفر TanStack Pacer تحديد معدل التنفيذ المتزامن وغير المتزامن من خلال فئات `RateLimiter` و `AsyncRateLimiter` على التوالي (ووظائفهما المقابلة `rateLimit` و `asyncRateLimit`). +يوفر TanStack Pacer تحديدًا مسبقًا لمعدل التنفيذ المتزامن وغير المتزامن من خلال فئتي `RateLimiter` و `AsyncRateLimiter` على التوالي (ووظائفهما المقابلة `rateLimit` و `asyncRateLimit`). ### الاستخدام الأساسي مع `rateLimit` -تعد وظيفة `rateLimit` أبسط طريقة لإضافة تحديد معدل التنفيذ إلى أي دالة. إنها مثالية لمعظم حالات الاستخدام حيث تحتاج فقط إلى فرض حد بسيط. +تعد وظيفة `rateLimit` أبسط طريقة لإضافة تحديد مسبق لمعدل التنفيذ إلى أي دالة. إنها مثالية لمعظم حالات الاستخدام حيث تحتاج فقط إلى فرض حد بسيط. ```ts import { rateLimit } from '@tanstack/pacer' -// تحديد معدل تنفيذ طلبات واجهة برمجة التطبيقات (API) إلى 5 في الدقيقة +// تحديد مسبق لمعدل تنفيذ استدعاءات واجهة برمجة التطبيقات (API) إلى 5 في الدقيقة const rateLimitedApi = rateLimit( (id: string) => fetchUserData(id), { limit: 5, window: 60 * 1000, // 1 دقيقة بالميلي ثانية + windowType: 'fixed', // افتراضي onReject: (rateLimiter) => { - console.log(`تم تجاوز حد التنفيذ. حاول مرة أخرى بعد ${rateLimiter.getMsUntilNextWindow()} مللي ثانية`) + console.log(`تم تجاوز الحد المسبق لمعدل التنفيذ. حاول مرة أخرى بعد ${rateLimiter.getMsUntilNextWindow()}ms`) } } ) @@ -73,17 +103,17 @@ rateLimitedApi('user-2') // ✅ يتم التنفيذ rateLimitedApi('user-3') // ✅ يتم التنفيذ rateLimitedApi('user-4') // ✅ يتم التنفيذ rateLimitedApi('user-5') // ✅ يتم التنفيذ -rateLimitedApi('user-6') // ❌ مرفوض حتى إعادة تعيين النافذة +rateLimitedApi('user-6') // ❌ يتم الرفض حتى إعادة تعيين النافذة ``` -### الاستخدام المتقدم مع فئة `RateLimiter` +### استخدام متقدم مع فئة `RateLimiter` -بالنسبة للسيناريوهات الأكثر تعقيدًا حيث تحتاج إلى تحكم إضافي في سلوك تحديد معدل التنفيذ، يمكنك استخدام فئة `RateLimiter` مباشرة. وهذا يمنحك الوصول إلى طرق إضافية ومعلومات الحالة. +بالنسبة للسيناريوهات الأكثر تعقيدًا حيث تحتاج إلى تحكم إضافي في سلوك التحديد المسبق لمعدل التنفيذ، يمكنك استخدام فئة `RateLimiter` مباشرة. وهذا يمنحك الوصول إلى طرق ومعلومات حالة إضافية. ```ts import { RateLimiter } from '@tanstack/pacer' -// إنشاء مثيل محدد معدل التنفيذ +// إنشاء مثيل محدد لمعدل التنفيذ const limiter = new RateLimiter( (id: string) => fetchUserData(id), { @@ -93,7 +123,7 @@ const limiter = new RateLimiter( console.log('تم تنفيذ الدالة', rateLimiter.getExecutionCount()) }, onReject: (rateLimiter) => { - console.log(`تم تجاوز حد التنفيذ. حاول مرة أخرى بعد ${rateLimiter.getMsUntilNextWindow()} مللي ثانية`) + console.log(`تم تجاوز الحد المسبق لمعدل التنفيذ. حاول مرة أخرى بعد ${rateLimiter.getMsUntilNextWindow()}ms`) } } ) @@ -117,6 +147,9 @@ limiter.reset() تدعم فئة `RateLimiter` التمكين/التعطيل عبر خيار `enabled`. باستخدام طريقة `setOptions`، يمكنك تمكين/تعطيل محدد معدل التنفيذ في أي وقت: +> [!ملاحظة] +> خيار `enabled` يمكّن/يعطل تنفيذ الدالة الفعلي. تعطيل محدد معدل التنفيذ لا يوقف التحديد المسبق لمعدل التنفيذ، بل يمنع فقط تنفيذ الدالة تمامًا. + ```ts const limiter = new RateLimiter(fn, { limit: 5, @@ -126,11 +159,11 @@ const limiter = new RateLimiter(fn, { limiter.setOptions({ enabled: true }) // تمكين في أي وقت ``` -إذا كنت تستخدم أداة تكيف إطار عمل حيث تكون خيارات محدد معدل التنفيذ تفاعلية، يمكنك تعيين خيار `enabled` إلى قيمة شرطية لتمكين/تعطيل محدد معدل التنفيذ على الفور. ومع ذلك، إذا كنت تستخدم وظيفة `rateLimit` أو فئة `RateLimiter` مباشرة، فيجب عليك استخدام طريقة `setOptions` لتغيير خيار `enabled`، حيث أن الخيارات التي يتم تمريرها يتم تمريرها بالفعل إلى مُنشئ فئة `RateLimiter`. +إذا كنت تستخدم أداة تكيف إطار عمل حيث تكون خيارات محدد معدل التنفيذ تفاعلية، يمكنك تعيين خيار `enabled` إلى قيمة شرطية لتمكين/تعطيل محدد معدل التنفيذ على الفور. ومع ذلك، إذا كنت تستخدم وظيفة `rateLimit` أو فئة `RateLimiter` مباشرة، يجب عليك استخدام طريقة `setOptions` لتغيير خيار `enabled`، حيث أن الخيارات التي يتم تمريرها يتم تمريرها بالفعل إلى مُنشئ فئة `RateLimiter`. -### خيارات ردود النداء (Callbacks) +### خيارات ردود النداء -يدعم كل من محددات معدل التنفيذ المتزامنة وغير المتزامنة خيارات ردود النداء للتعامل مع جوانب مختلفة من دورة حياة تحديد معدل التنفيذ: +يدعم كل من محددات معدل التنفيذ المتزامنة وغير المتزامنة خيارات ردود النداء للتعامل مع جوانب مختلفة من دورة حياة التحديد المسبق لمعدل التنفيذ: #### ردود نداء محدد معدل التنفيذ المتزامن @@ -145,17 +178,17 @@ const limiter = new RateLimiter(fn, { console.log('تم تنفيذ الدالة', rateLimiter.getExecutionCount()) }, onReject: (rateLimiter) => { - // يتم استدعاؤها عند رفض التنفيذ - console.log(`تم تجاوز حد التنفيذ. حاول مرة أخرى بعد ${rateLimiter.getMsUntilNextWindow()} مللي ثانية`) + // يتم استدعاؤها عند رفض تنفيذ + console.log(`تم تجاوز الحد المسبق لمعدل التنفيذ. حاول مرة أخرى بعد ${rateLimiter.getMsUntilNextWindow()}ms`) } }) ``` -يتم استدعاء رد النداء `onExecute` بعد كل تنفيذ ناجح للدالة محددة المعدل، بينما يتم استدعاء رد النداء `onReject` عند رفض التنفيذ بسبب تحديد معدل التنفيذ. تعد ردود النداء هذه مفيدة لتتبع عمليات التنفيذ، وتحديث حالة واجهة المستخدم، أو توفير ملاحظات للمستخدمين. +يتم استدعاء رد النداء `onExecute` بعد كل تنفيذ ناجح للدالة المحددة مسبقًا لمعدل التنفيذ، بينما يتم استدعاء رد النداء `onReject` عند رفض تنفيذ بسبب التحديد المسبق لمعدل التنفيذ. تعد ردود النداء هذه مفيدة لتتبع عمليات التنفيذ، وتحديث حالة واجهة المستخدم، أو توفير ملاحظات للمستخدمين. #### ردود نداء محدد معدل التنفيذ غير المتزامن -يدعم `AsyncRateLimiter` غير المتزامن ردود نداء إضافية للتعامل مع الأخطاء: +يدعم `AsyncRateLimiter` ردود نداء إضافية للتعامل مع الأخطاء: ```ts const asyncLimiter = new AsyncRateLimiter(async (id) => { @@ -168,8 +201,8 @@ const asyncLimiter = new AsyncRateLimiter(async (id) => { console.log('تم تنفيذ الدالة غير المتزامنة', rateLimiter.getExecutionCount()) }, onReject: (rateLimiter) => { - // يتم استدعاؤها عند رفض التنفيذ - console.log(`تم تجاوز حد التنفيذ. حاول مرة أخرى بعد ${rateLimiter.getMsUntilNextWindow()} مللي ثانية`) + // يتم استدعاؤها عند رفض تنفيذ + console.log(`تم تجاوز الحد المسبق لمعدل التنفيذ. حاول مرة أخرى بعد ${rateLimiter.getMsUntilNextWindow()}ms`) }, onError: (error) => { // يتم استدعاؤها إذا ألقت الدالة غير المتزامنة خطأ @@ -178,73 +211,28 @@ const asyncLimiter = new AsyncRateLimiter(async (id) => { }) ``` -تعمل ردود النداء `onExecute` و `onReject` بنفس الطريقة كما في محدد معدل التنفيذ المتزامن، بينما يسمح رد النداء `onError` لك بالتعامل مع الأخطاء بسلاسة دون كسر سلسلة تحديد معدل التنفيذ. تعد ردود النداء هذه مفيدة بشكل خاص لتتبع عدد عمليات التنفيذ، وتحديث حالة واجهة المستخدم، والتعامل مع الأخطاء، وتوفير ملاحظات للمستخدمين. +تعمل ردود النداء `onExecute` و `onReject` بنفس الطريقة كما في محدد معدل التنفيذ المتزامن، بينما يسمح رد النداء `onError` بالتعامل مع الأخطاء بأمان دون كسر سلسلة التحديد المسبق لمعدل التنفيذ. تعد ردود النداء هذه مفيدة بشكل خاص لتتبع عدد عمليات التنفيذ، وتحديث حالة واجهة المستخدم، والتعامل مع الأخطاء، وتوفير ملاحظات للمستخدمين. -### تحديد معدل التنفيذ غير المتزامن +### التحديد المسبق لمعدل التنفيذ غير المتزامن -يوفر محدد معدل التنفيذ غير المتزامن طريقة قوية للتعامل مع العمليات غير المتزامنة مع تحديد معدل التنفيذ، ويقدم عدة مزايا رئيسية مقارنة بالإصدار المتزامن. بينما يعد محدد معدل التنفيذ المتزامن رائعًا لأحداث واجهة المستخدم والملاحظات الفورية، فإن الإصدار غير المتزامن مصمم خصيصًا للتعامل مع استدعاءات واجهة برمجة التطبيقات (API)، وعمليات قاعدة البيانات، والمهام غير المتزامنة الأخرى. +يوفر محدد معدل التنفيذ غير المتزامن طريقة قوية للتعامل مع العمليات غير المتزامنة مع التحديد المسبق لمعدل التنفيذ، ويقدم عدة مزايا رئيسية مقارنة بالإصدار المتزامن. بينما يعد محدد معدل التنفيذ المتزامن رائعًا لأحداث واجهة المستخدم والملاحظات الفورية، فإن الإصدار غير المتزامن مصمم خصيصًا للتعامل مع استدعاءات واجهة برمجة التطبيقات (API)، وعمليات قاعدة البيانات، والمهام غير المتزامنة الأخرى. -#### الاختلافات الرئيسية عن تحديد معدل التنفيذ المتزامن +#### الاختلافات الرئيسية عن التحديد المسبق لمعدل التنفيذ المتزامن -1. **معالجة القيمة المرجعة** -على عكس محدد معدل التنفيذ المتزامن الذي يُرجع قيمة منطقية تشير إلى النجاح، يسمح الإصدار غير المتزامن لك بالتقاط واستخدام القيمة المرجعة من الدالة محددة المعدل. هذا مفيد بشكل خاص عندما تحتاج إلى العمل مع نتائج استدعاءات واجهة برمجة التطبيقات (API) أو العمليات غير المتزامنة الأخرى. تُرجع طريقة `maybeExecute` وعدًا (Promise) يحل بقيمة إرجاع الدالة، مما يسمح لك بانتظار النتيجة والتعامل معها بشكل مناسب. +1. **معالجة قيمة الإرجاع** +على عكس محدد معدل التنفيذ المتزامن الذي يُرجع قيمة منطقية تشير إلى النجاح، يسمح الإصدار غير المتزامن لك بالتقاط واستخدام قيمة الإرجاع من الدالة المحددة مسبقًا لمعدل التنفيذ. وهذا مفيد بشكل خاص عندما تحتاج إلى العمل مع نتائج استدعاءات واجهة برمجة التطبيقات (API) أو العمليات غير المتزامنة الأخرى. تُرجع طريقة `maybeExecute` وعدًا (Promise) يتم حله بقيمة إرجاع الدالة، مما يسمح لك بانتظار النتيجة والتعامل معها بشكل مناسب. -2. **نظام ردود النداء المحسن** -يوفر محدد معدل التنفيذ غير المتزامن نظام ردود نداء أكثر تطورًا مقارنة بردود النداء الخاصة بالإصدار المتزامن. يتضمن هذا النظام: -- `onExecute`: يتم استدعاؤها بعد كل تنفيذ ناجح، وتوفر مثيل محدد معدل التنفيذ -- `onReject`: يتم استدعاؤها عند رفض التنفيذ بسبب تحديد معدل التنفيذ، وتوفر مثيل محدد معدل التنفيذ +2. **ردود نداء مختلفة** +يدعم `AsyncRateLimiter` ردود النداء التالية بدلاً من `onExecute` فقط في الإصدار المتزامن: +- `onSuccess`: يتم استدعاؤها بعد كل تنفيذ ناجح، وتوفر مثيل محدد معدل التنفيذ +- `onSettled`: يتم استدعاؤها بعد كل تنفيذ، وتوفر مثيل محدد معدل التنفيذ - `onError`: يتم استدعاؤها إذا ألقت الدالة غير المتزامنة خطأ، وتوفر كلًا من الخطأ ومثيل محدد معدل التنفيذ -3. **تتبع التنفيذ** -يوفر محدد معدل التنفيذ غير المتزامن تتبعًا شاملاً للتنفيذ من خلال عدة طرق: -- `getExecutionCount()`: عدد عمليات التنفيذ الناجحة -- `getRejectionCount()`: عدد عمليات التنفيذ المرفوضة -- `getRemainingInWindow()`: عدد عمليات التنفيذ المتبقية في النافذة الحالية -- `getMsUntilNextWindow()`: عدد المللي ثانية حتى بدء النافذة التالية - -4. **التنفيذ التسلسلي** -يضمن محدد معدل التنفيذ غير المتزامن أن عمليات التنفيذ اللاحقة تنتظر اكتمال الاستدعاء السابق قبل البدء. هذا يمنع التنفيذ خارج الترتيب ويضمن أن كل استدعاء يعالج أحدث البيانات. هذا مهم بشكل خاص عند التعامل مع العمليات التي تعتمد على نتائج الاستدعاءات السابقة أو عندما يكون الحفاظ على اتساق البيانات أمرًا بالغ الأهمية. - -على سبيل المثال، إذا كنت تقوم بتحديث ملف تعريف المستخدم ثم تقوم على الفور جلب بياناته المحدثة، فإن محدد معدل التنفيذ غير المتزامن سيتأكد من انتظار عملية الجلب لإكمال التحديث، مما يمنع ظروف السباق (race conditions) حيث قد تحصل على بيانات قديمة. - -#### مثال على الاستخدام الأساسي - -إليك مثالًا أساسيًا يوضح كيفية استخدام محدد معدل التنفيذ غير المتزامن لعملية واجهة برمجة التطبيقات (API): - -```ts -const rateLimitedApi = asyncRateLimit( - async (id: string) => { - const response = await fetch(`/api/data/${id}`) - return response.json() - }, - { - limit: 5, - window: 1000, - onExecute: (limiter) => { - console.log('نجاح استدعاء واجهة برمجة التطبيقات (API):', limiter.getExecutionCount()) - }, - onReject: (limiter) => { - console.log(`تم تجاوز حد التنفيذ. حاول مرة أخرى بعد ${limiter.getMsUntilNextWindow()} مللي ثانية`) - }, - onError: (error, limiter) => { - console.error('فشل استدعاء واجهة برمجة التطبيقات (API):', error) - } - } -) - -// الاستخدام -const result = await rateLimitedApi('123') -``` - -#### الأنماط المتقدمة - -يمكن دمج محدد معدل التنفيذ غير المتزامن مع أنماط مختلفة لحل المشكلات المعقدة: +يدعم كل من محددات معدل التنفيذ غير المتزامنة والمتزامنة رد النداء `onReject` للتعامل مع عمليات التنفيذ المحظورة. -1. **تكامل إدارة الحالة** -عند استخدام محدد معدل التنفيذ غير المتزامن مع أنظمة إدارة الحالة (مثل useState في React أو createSignal في Solid)، يمكنك إنشاء أنماط قوية للتعامل مع حالات التحميل، وحالات الخطأ، وتحديثات البيانات. توفر ردود النداء الخاصة بمحدد معدل التنفيذ خطافات مثالية لتحديث حالة واجهة المستخدم بناءً على نجاح أو فشل العمليات. +3. **التنفيذ المتسلسل** +نظرًا لأن طريقة `maybeExecute` لمحدد معدل التنفيذ تُرجع وعدًا (Promise)، يمكنك اختيار انتظار كل تنفيذ قبل بدء التالي. وهذا يمنحك التحكم في ترتيب التنفيذ ويضمن معالجة كل استدعاء لأحدث البيانات. وهذا مفيد بشكل خاص عند التعامل مع العمليات التي تعتمد على نتائج الاستدعاءات السابقة أو عندما يكون الحفاظ على اتساق البيانات أمرًا بالغ الأهمية. -2. **منع ظروف السباق (Race Conditions)** -يمنع نمط تحديد معدل التنفيذ ظروف السباق في العديد من السيناريوهات بشكل طبيعي. عندما تحاول أجزاء متعددة من تطبيقك تحديث نفس المورد في نفس الوقت، يضمن محدد معدل التنفيذ حدوث التحديثات ضمن الحدود المكونة، مع توفير النتائج لجميع المتصلين. +على سبيل المثال، إذا كنت تقوم بتحديث ملف تعريف المستخدم ثم تقوم على الفور جلب بياناته المحدثة، يمكنك انتظار عملية التحديث قبل بدء الجلب: -3. **استعادة الخطأ** -تج +#### مثال على الاستخدام الأساس diff --git a/docs/ar/guides/throttling.md b/docs/ar/guides/throttling.md index 439f2fd28..bba73a17a 100644 --- a/docs/ar/guides/throttling.md +++ b/docs/ar/guides/throttling.md @@ -1,18 +1,18 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:22:36.353Z' -title: ديل التخفيف (Throttling) +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:05:07.488Z' +title: دليل التخفيف (Throttling) id: throttling --- -# دليل التحديد (Throttling) +# دليل التحديد (Throttling) -الحد من المعدل (Rate Limiting)، التحديد (Throttling)، وإلغاء الاهتزاز (Debouncing) هي ثلاث طرق مختلفة للتحكم في تكرار تنفيذ الدوال. كل تقنية تمنع عمليات التنفيذ بطريقة مختلفة، مما يجعلها "فاقدة" (lossy) - أي أن بعض استدعاءات الدوال لن تنفذ عند طلب تشغيلها بشكل متكرر جدًا. فهم متى تستخدم كل طريقة أمر بالغ الأهمية لبناء تطبيقات عالية الأداء وموثوقة. سيتناول هذا الدليل مفاهيم التحديد (Throttling) في TanStack Pacer. +التحديد المعدل (Rate Limiting)، التحديد (Throttling)، والتخفيف (Debouncing) هي ثلاث طرق مختلفة للتحكم في تكرار تنفيذ الدوال. كل تقنية تمنع عمليات التنفيذ بشكل مختلف، مما يجعلها "فاقدة" - بمعنى أن بعض استدعاءات الدوال لن تنفذ عند طلب تشغيلها بشكل متكرر جدًا. فهم الوقت المناسب لاستخدام كل أسلوب أمر بالغ الأهمية لبناء تطبيقات عالية الأداء وموثوقة. سيغطي هذا الدليل مفاهيم التحديد (Throttling) في TanStack Pacer. -## مفهوم التحديد (Throttling) +## مفهوم التحديد (Throttling) -يضمن التحديد (Throttling) توزيع عمليات تنفيذ الدوال بشكل متساوٍ عبر الزمن. على عكس الحد من المعدل (Rate Limiting) الذي يسمح بتنفيذ دفعات من الاستدعاءات حتى حد معين، أو إلغاء الاهتزاز (Debouncing) الذي ينتظر توقف النشاط، فإن التحديد (Throttling) ينشئ نمط تنفيذ أكثر سلاسة من خلال فرض تأخيرات ثابتة بين الاستدعاءات. إذا قمت بتعيين تحديد (Throttling) لتنفيذ واحد كل ثانية، فسيتم توزيع الاستدعاءات بشكل متساوٍ بغض النظر عن مدى سرعة طلبها. +يضمن التحديد (Throttling) توزيع عمليات تنفيذ الدوال بشكل متساوٍ عبر الزمن. على عكس التحديد المعدل (Rate Limiting) الذي يسمح باندفاعات من عمليات التنفيذ حتى حد معين، أو التخفيف (Debouncing) الذي ينتظر توقف النشاط، فإن التحديد (Throttling) ينشئ نمط تنفيذ أكثر سلاسة من خلال فرض تأخيرات ثابتة بين الاستدعاءات. إذا قمت بتعيين تحديد (Throttling) لتنفيذ واحد كل ثانية، فسيتم توزيع الاستدعاءات بشكل متساوٍ بغض النظر عن مدى سرعة طلبها. -### تصور التحديد (Throttling) +### تصور التحديد (Throttling) ```text Throttling (one execution per 3 ticks) @@ -28,34 +28,34 @@ Executed: ✅ ❌ ⏳ -> ✅ ❌ ❌ ❌ ✅ ✅ then throttle wait period wait period passes ``` -### متى تستخدم التحديد (Throttling) +### متى تستخدم التحديد (Throttling) -التحديد (Throttling) فعال بشكل خاص عندما تحتاج إلى توقيت تنفيذ متسق ومتوقع. هذا يجعله مثاليًا للتعامل مع الأحداث أو التحديثات المتكررة حيث تريد سلوكًا سلسًا ومسيطرًا عليه. +التحديد (Throttling) فعال بشكل خاص عندما تحتاج إلى توقيت تنفيذ ثابت ومتوقع. هذا يجعله مثاليًا للتعامل مع الأحداث أو التحديثات المتكررة حيث تريد سلوكًا سلسًا ومسيطرًا عليه. -من حالات الاستخدام الشائعة: -- تحديثات واجهة المستخدم التي تحتاج إلى توقيت متسق (مثل مؤشرات التقدم) -- معالجات أحداث التمرير (Scroll) أو تغيير الحجم (Resize) التي لا يجب أن تثقل المتصفح -- جلب البيانات في الوقت الفعلي (Real-time polling) حيث تكون الفواصل الزمنية المتسقة مطلوبة -- العمليات كثيفة الاستهلاك للموارد التي تحتاج إلى وتيرة ثابتة -- تحديثات حلقة اللعبة (Game loop) أو معالجة إطارات الرسوم المتحركة -- اقتراحات البحث المباشر أثناء كتابة المستخدم +حالات الاستخدام الشائعة تشمل: +- تحديثات واجهة المستخدم التي تحتاج إلى توقيت ثابت (مثل مؤشرات التقدم) +- معالجات أحداث التمرير (Scroll) أو تغيير الحجم (Resize) التي لا يجب أن تثقل المتصفح +- استطلاع البيانات في الوقت الفعلي حيث تكون الفواصل الزمنية الثابتة مرغوبة +- العمليات كثيفة الموارد التي تحتاج إلى وتيرة ثابتة +- تحديثات حلقة اللعبة (Game loop) أو معالجة إطار الرسوم المتحركة +- اقتراحات البحث المباشر أثناء كتابة المستخدمين -### متى لا تستخدم التحديد (Throttling) +### متى لا تستخدم التحديد (Throttling) -قد لا يكون التحديد (Throttling) هو الخيار الأفضل عندما: -- تريد الانتظار حتى يتوقف النشاط (استخدم [إلغاء الاهتزاز (Debouncing)](../guides/debouncing) بدلاً من ذلك) -- لا يمكنك تحمل فقدان أي عمليات تنفيذ (استخدم [الطابور (Queueing)](../guides/queueing) بدلاً من ذلك) +قد لا يكون التحديد (Throttling) هو الخيار الأفضل عندما: +- تريد الانتظار حتى يتوقف النشاط (استخدم [التخفيف (Debouncing)](../guides/debouncing) بدلاً من ذلك) +- لا يمكنك تحمل فقدان أي عمليات تنفيذ (استخدم [الطوابير (Queueing)](../guides/queueing) بدلاً من ذلك) -> [!TIP] -> غالبًا ما يكون التحديد (Throttling) هو الخيار الأفضل عندما تحتاج إلى توقيت تنفيذ سلس ومتسق. فهو يوفر نمط تنفيذ أكثر قابلية للتنبؤ من الحد من المعدل (Rate Limiting) وردود فعل أكثر فورية من إلغاء الاهتزاز (Debouncing). +> [!TIP] +> غالبًا ما يكون التحديد (Throttling) هو الخيار الأفضل عندما تحتاج إلى توقيت تنفيذ سلس وثابت. فهو يوفر نمط تنفيذ أكثر قابلية للتنبؤ من التحديد المعدل (Rate Limiting) وردود فعل أكثر فورية من التخفيف (Debouncing). -## التحديد (Throttling) في TanStack Pacer +## التحديد (Throttling) في TanStack Pacer -يوفر TanStack Pacer التحديد (Throttling) المتزامن وغير المتزامن من خلال الفئات `Throttler` و `AsyncThrottler` على التوالي (والدوال المقابلة لهما `throttle` و `asyncThrottle`). +يوفر TanStack Pacer كلاً من التحديد المتزامن وغير المتزامن من خلال فئتي `Throttler` و `AsyncThrottler` على التوالي (ووظائفهما المقابلة `throttle` و `asyncThrottle`). -### الاستخدام الأساسي مع `throttle` +### الاستخدام الأساسي مع `throttle` -تعد دالة `throttle` أبسط طريقة لإضافة التحديد (Throttling) إلى أي دالة: +تعتبر دالة `throttle` أبسط طريقة لإضافة تحديد (Throttling) إلى أي دالة: ```ts import { throttle } from '@tanstack/pacer' @@ -68,15 +68,15 @@ const throttledUpdate = throttle( } ) -// في حلقة سريعة، يتم التنفيذ فقط كل 200 مللي ثانية +// في حلقة سريعة، ينفذ فقط كل 200 مللي ثانية for (let i = 0; i < 100; i++) { - throttledUpdate(i) // العديد من الاستدعاءات يتم تحديدها (Throttled) + throttledUpdate(i) // العديد من الاستدعاءات يتم تحديدها } ``` -### استخدام متقدم مع فئة `Throttler` +### الاستخدام المتقدم مع فئة `Throttler` -لمزيد من التحكم في سلوك التحديد (Throttling)، يمكنك استخدام فئة `Throttler` مباشرة: +لمزيد من التحكم في سلوك التحديد (Throttling)، يمكنك استخدام فئة `Throttler` مباشرة: ```ts import { Throttler } from '@tanstack/pacer' @@ -94,46 +94,46 @@ console.log(updateThrottler.getLastExecutionTime()) // الطابع الزمني updateThrottler.cancel() ``` -### التنفيذ الأولي والنهائي +### عمليات التنفيذ الأولية والنهائية (Leading and Trailing) -يدعم المحدد (Throttler) المتزامن عمليات التنفيذ على الحافة الأولية (Leading) والنهائية (Trailing): +يدعم المحدد المتزامن كلاً من عمليات التنفيذ على الحافة الأولية والنهائية: ```ts const throttledFn = throttle(fn, { wait: 200, - leading: true, // التنفيذ على أول استدعاء (افتراضي) + leading: true, // التنفيذ فورًا عند أول استدعاء (افتراضي) trailing: true, // التنفيذ بعد فترة الانتظار (افتراضي) }) ``` -- `leading: true` (افتراضي) - التنفيذ فورًا عند أول استدعاء -- `leading: false` - تخطي أول استدعاء، انتظر التنفيذ النهائي -- `trailing: true` (افتراضي) - تنفيذ آخر استدعاء بعد فترة الانتظار -- `trailing: false` - تخطي آخر استدعاء إذا كان ضمن فترة الانتظار +- `leading: true` (افتراضي) - التنفيذ فورًا عند أول استدعاء +- `leading: false` - تخطي أول استدعاء، الانتظار للتنفيذ النهائي +- `trailing: true` (افتراضي) - تنفيذ آخر استدعاء بعد فترة الانتظار +- `trailing: false` - تخطي آخر استدعاء إذا كان ضمن فترة الانتظار -أنماط شائعة: -- `{ leading: true, trailing: true }` - الافتراضي، الأكثر استجابة -- `{ leading: false, trailing: true }` - تأخير جميع عمليات التنفيذ -- `{ leading: true, trailing: false }` - تخطي عمليات التنفيذ في الطابور +أنماط شائعة: +- `{ leading: true, trailing: true }` - افتراضي، أكثر استجابة +- `{ leading: false, trailing: true }` - تأخير جميع عمليات التنفيذ +- `{ leading: true, trailing: false }` - تخطي عمليات التنفيذ في قائمة الانتظار -### التمكين/التعطيل +### التمكين/التعطيل -تدعم فئة `Throttler` التمكين/التعطيل عبر خيار `enabled`. باستخدام طريقة `setOptions`، يمكنك تمكين/تعطيل المحدد (Throttler) في أي وقت: +تدعم فئة `Throttler` التمكين/التعطيل عبر خيار `enabled`. باستخدام طريقة `setOptions`، يمكنك تمكين/تعطيل المحدد في أي وقت: ```ts const throttler = new Throttler(fn, { wait: 200, enabled: false }) // تعطيل افتراضيًا throttler.setOptions({ enabled: true }) // تمكين في أي وقت ``` -إذا كنت تستخدم أداة تكيف إطار عمل حيث تكون خيارات المحدد (Throttler) تفاعلية، يمكنك تعيين خيار `enabled` إلى قيمة شرطية لتمكين/تعطيل المحدد (Throttler) على الفور. ومع ذلك، إذا كنت تستخدم دالة `throttle` أو فئة `Throttler` مباشرة، فيجب عليك استخدام طريقة `setOptions` لتغيير خيار `enabled`، حيث أن الخيارات التي يتم تمريرها يتم تمريرها بالفعل إلى مُنشئ فئة `Throttler`. +إذا كنت تستخدم أداة تكيف إطار عمل حيث تكون خيارات المحدد تفاعلية، يمكنك تعيين خيار `enabled` إلى قيمة شرطية لتمكين/تعطيل المحدد على الفور. ومع ذلك، إذا كنت تستخدم دالة `throttle` أو فئة `Throttler` مباشرة، يجب عليك استخدام طريقة `setOptions` لتغيير خيار `enabled`، حيث أن الخيارات التي يتم تمريرها يتم تمريرها بالفعل إلى منشئ فئة `Throttler`. -### خيارات رد النداء (Callback) +### خيارات رد النداء (Callback Options) -يدعم كل من المحدد (Throttler) المتزامن وغير المتزامن خيارات رد النداء (Callback) للتعامل مع جوانب مختلفة من دورة حياة التحديد (Throttling): +يدعم كل من المحدد المتزامن وغير المتزامن خيارات رد النداء للتعامل مع جوانب مختلفة من دورة حياة التحديد (Throttling): -#### ردود نداء المحدد (Throttler) المتزامن +#### ردود نداء المحدد المتزامن -يدعم المحدد (Throttler) المتزامن رد النداء التالي: +يدعم `Throttler` المتزامن رد النداء التالي: ```ts const throttler = new Throttler(fn, { @@ -145,11 +145,11 @@ const throttler = new Throttler(fn, { }) ``` -يتم استدعاء رد النداء `onExecute` بعد كل تنفيذ ناجح للدالة المحددة (Throttled)، مما يجعله مفيدًا لتتبع عمليات التنفيذ، تحديث حالة واجهة المستخدم، أو تنفيذ عمليات التنظيف. +يتم استدعاء رد النداء `onExecute` بعد كل تنفيذ ناجح للدالة المحددة، مما يجعله مفيدًا لتتبع عمليات التنفيذ، تحديث حالة واجهة المستخدم، أو تنفيذ عمليات التنظيف. -#### ردود نداء المحدد (AsyncThrottler) غير المتزامن +#### ردود نداء المحدد غير المتزامن -يدعم المحدد (AsyncThrottler) غير المتزامن ردود نداء إضافية للتعامل مع الأخطاء: +يدعم `AsyncThrottler` غير المتزامن ردود نداء إضافية للتعامل مع الأخطاء: ```ts const asyncThrottler = new AsyncThrottler(async (value) => { @@ -167,37 +167,33 @@ const asyncThrottler = new AsyncThrottler(async (value) => { }) ``` -يعمل رد النداء `onExecute` بنفس الطريقة كما في المحدد (Throttler) المتزامن، بينما يسمح رد النداء `onError` بالتعامل مع الأخطاء بسهولة دون كسر سلسلة التحديد (Throttling). تعد ردود النداء هذه مفيدة بشكل خاص لتتبع عدد عمليات التنفيذ، تحديث حالة واجهة المستخدم، التعامل مع الأخطاء، تنفيذ عمليات التنظيف، وتسجيل مقاييس التنفيذ. +يعمل رد النداء `onExecute` بنفس الطريقة كما في المحدد المتزامن، بينما يسمح رد النداء `onError` لك بالتعامل مع الأخطاء بأمان دون كسر سلسلة التحديد (Throttling). تعد ردود النداء هذه مفيدة بشكل خاص لتتبع عدد عمليات التنفيذ، تحديث حالة واجهة المستخدم، التعامل مع الأخطاء، تنفيذ عمليات التنظيف، وتسجيل مقاييس التنفيذ. -### التحديد غير المتزامن (Async Throttling) +### التحديد غير المتزامن (Asynchronous Throttling) -يوفر المحدد غير المتزامن (AsyncThrottler) طريقة قوية للتعامل مع العمليات غير المتزامنة مع التحديد (Throttling)، ويقدم عدة مزايا رئيسية مقارنة بالإصدار المتزامن. بينما يكون المحدد المتزامن رائعًا لأحداث واجهة المستخدم والردود الفورية، فإن الإصدار غير المتزامن مصمم خصيصًا للتعامل مع استدعاءات API، عمليات قاعدة البيانات، والمهام غير المتزامنة الأخرى. +يوفر المحدد غير المتزامن طريقة قوية للتعامل مع العمليات غير المتزامنة مع التحديد (Throttling)، حيث يقدم عدة مزايا رئيسية مقارنة بالإصدار المتزامن. بينما يكون المحدد المتزامن رائعًا لأحداث واجهة المستخدم وردود الفعل الفورية، فإن الإصدار غير المتزامن مصمم خصيصًا للتعامل مع استدعاءات API، عمليات قاعدة البيانات، والمهام غير المتزامنة الأخرى. -#### الاختلافات الرئيسية عن التحديد المتزامن +#### الاختلافات الرئيسية عن التحديد المتزامن -1. **معالجة قيمة الإرجاع** -على عكس المحدد المتزامن الذي يُرجع `void`، يسمح الإصدار غير المتزامن بالتقاط واستخدام قيمة الإرجاع من الدالة المحددة (Throttled). هذا مفيد بشكل خاص عندما تحتاج إلى العمل مع نتائج استدعاءات API أو العمليات غير المتزامنة الأخرى. تُرجع طريقة `maybeExecute` وعدًا (Promise) يحل بقيمة إرجاع الدالة، مما يسمح لك بالانتظار (await) للنتيجة والتعامل معها بشكل مناسب. +1. **معالجة القيمة المرجعة** +على عكس المحدد المتزامن الذي يُرجع void، يسمح الإصدار غير المتزامن لك بالتقاط واستخدام القيمة المرجعة من دالتك المحددة. هذا مفيد بشكل خاص عندما تحتاج إلى العمل مع نتائج استدعاءات API أو العمليات غير المتزامنة الأخرى. تُرجع طريقة `maybeExecute` وعدًا (Promise) يحل بقيمة إرجاع الدالة، مما يسمح لك بانتظار النتيجة والتعامل معها بشكل مناسب. -2. **نظام رد نداء محسن** -يوفر المحدد غير المتزامن (AsyncThrottler) نظام رد نداء أكثر تطورًا مقارنة برد النداء الفردي `onExecute` في الإصدار المتزامن. يتضمن هذا النظام: -- `onSuccess`: يتم استدعاؤه عند اكتمال الدالة غير المتزامنة بنجاح، مع توفير كل من النتيجة ومثيل المحدد (Throttler) -- `onError`: يتم استدعاؤه عند حدوث خطأ في الدالة غير المتزامنة، مع توفير كل من الخطأ ومثيل المحدد (Throttler) -- `onSettled`: يتم استدعاؤه بعد كل محاولة تنفيذ، بغض النظر عن النجاح أو الفشل +2. **ردود نداء مختلفة** +يدعم `AsyncThrottler` ردود النداء التالية بدلاً من `onExecute` فقط في الإصدار المتزامن: +- `onSuccess`: يتم استدعاؤه بعد كل تنفيذ ناجح، مع توفير مثيل المحدد +- `onSettled`: يتم استدعاؤه بعد كل تنفيذ، مع توفير مثيل المحدد +- `onError`: يتم استدعاؤه إذا ألقت الدالة غير المتزامنة خطأ، مع توفير كل من الخطأ ومثيل المحدد -3. **تتبع التنفيذ** -يوفر المحدد غير المتزامن (AsyncThrottler) تتبعًا شاملاً للتنفيذ من خلال عدة طرق: -- `getSuccessCount()`: عدد عمليات التنفيذ الناجحة -- `getErrorCount()`: عدد عمليات التنفيذ الفاشلة -- `getSettledCount()`: إجمالي عدد عمليات التنفيذ المكتملة (النجاح + الفشل) +كلا المحددين المتزامن وغير المتزامن يدعمان رد النداء `onExecute` للتعامل مع عمليات التنفيذ الناجحة. -4. **التنفيذ التسلسلي** -يضمن المحدد غير المتزامن (AsyncThrottler) أن عمليات التنفيذ اللاحقة تنتظر اكتمال الاستدعاء السابق قبل البدء. هذا يمنع التنفيذ خارج الترتيب ويضمن أن كل استدعاء يعالج أحدث البيانات. هذا مهم بشكل خاص عند التعامل مع العمليات التي تعتمد على نتائج الاستدعاءات السابقة أو عندما يكون الحفاظ على تناسق البيانات أمرًا بالغ الأهمية. +3. **التنفيذ المتسلسل** +نظرًا لأن طريقة `maybeExecute` للمحدد تُرجع وعدًا (Promise)، يمكنك اختيار انتظار كل تنفيذ قبل بدء التالي. وهذا يمنحك التحكم في ترتيب التنفيذ ويضمن معالجة كل استدعاء لأحدث البيانات. هذا مفيد بشكل خاص عند التعامل مع العمليات التي تعتمد على نتائج الاستدعاءات السابقة أو عندما يكون الحفاظ على اتساق البيانات أمرًا بالغ الأهمية. -على سبيل المثال، إذا كنت تقوم بتحديث ملف تعريف المستخدم ثم جلب بياناته المحدثة على الفور، فإن المحدد غير المتزامن (AsyncThrottler) سيضمن أن عملية الجلب تنتظر اكتمال التحديث، مما يمنع حالات السباق (Race conditions) حيث قد تحصل على بيانات قديمة. +على سبيل المثال، إذا كنت تقوم بتحديث ملف تعريف المستخدم ثم جلب بياناته المحدثة على الفور، يمكنك انتظار عملية التحديث قبل بدء الجلب: -#### مثال على الاستخدام الأساسي +#### مثال على الاستخدام الأساسي -إليك مثالًا أساسيًا يوضح كيفية استخدام المحدد غير المتزامن (AsyncThrottler) لعملية بحث: +إليك مثالاً أساسيًا يوضح كيفية استخدام المحدد غير المتزامن لعملية بحث: ```ts const throttledSearch = asyncThrottle( @@ -208,7 +204,7 @@ const throttledSearch = asyncThrottle( { wait: 500, onSuccess: (results, throttler) => { - console.log('نجاح البحث:', results) + console.log('نجح البحث:', results) }, onError: (error, throttler) => { console.error('فشل البحث:', error) @@ -220,26 +216,13 @@ const throttledSearch = asyncThrottle( const results = await throttledSearch('query') ``` -#### أنماط متقدمة +### أدوات تكيف الأطر (Framework Adapters) -يمكن دمج المحدد غير المتزامن (AsyncThrottler) مع أنماط مختلفة لحل المشكلات المعقدة: +توفر كل أداة تكيف إطار خطاطيف (hooks) تعتمد على وظائف التحديد الأساسية للدمج مع نظام إدارة الحالة الخاص بالإطار. تتوفر خطاطيف مثل `createThrottler`، `useThrottledCallback`، `useThrottledState`، أو `useThrottledValue` لكل إطار. -1. **تكامل إدارة الحالة** -عند استخدام المحدد غير المتزامن (AsyncThrottler) مع أنظمة إدارة الحالة (مثل useState في React أو createSignal في Solid)، يمكنك إنشاء أنماط قوية للتعامل مع حالات التحميل، حالات الخطأ، وتحديثات البيانات. توفر ردود نداء المحدد (Throttler) خطافات مثالية لتحديث حالة واجهة المستخدم بناءً على نجاح أو فشل العمليات. +إليك بعض الأمثلة: -2. **منع حالات السباق (Race Conditions)** -يمنع نمط التحديد (Throttling) حالات السباق (Race Conditions) في العديد من السيناريوهات. عندما تحاول أجزاء متعددة من تطبيقك تحديث نفس المورد في نفس الوقت، يضمن المحدد (Throttler) حدوث التحديثات بمعدل مسيطر عليه، مع توفير النتائج لجميع المستدعين. - -3. **استعادة الخطأ** -تجعل قدرات التعامل مع الأخطاء في المحدد غير المتزامن (AsyncThrottler) مثاليًا لتنفيذ منطق إعادة المحاولة وأنماط استعادة الخطأ. يمكنك استخدام رد النداء `onError` لتنفيذ استراتيجيات التعامل مع الأخطاء المخصصة، مثل التراجع الأسي (Exponential backoff) أو آليات الاحتياط. - -### أدوات تكيف الأطر (Framework Adapters) - -يوفر كل أداة تكيف إطار خطافات (Hooks) تعتمد على وظائف التحديد (Throttling) الأساسية للتكامل مع نظام إدارة الحالة الخاص بالإطار. تتوفر خطافات مثل `createThrottler`، `useThrottledCallback`، `useThrottledState`، أو `useThrottledValue` لكل إطار. - -إليك بعض الأمثلة: - -#### React +#### React ```tsx import { useThrottler, useThrottledCallback, useThrottledValue } from '@tanstack/react-pacer' @@ -256,17 +239,32 @@ const handleUpdate = useThrottledCallback( { wait: 200 } ) -// خطاف يعتمد على الحالة لإدارة الحالة التفاعلية +// خطاف قائم على الحالة لإدارة الحالة التفاعلية const [instantState, setInstantState] = useState(0) const [throttledValue] = useThrottledValue( - instantState, // القيمة المطلوب تحديدها (Throttle) + instantState, // القيمة المطلوب تحديدها { wait: 200 } ) ``` -#### Solid +#### Solid ```tsx import { createThrottler, createThrottledSignal } from '@tanstack/solid-pacer' -// خطاف منخ +// خطاف منخفض المستوى للتحكم الكامل +const throttler = createThrottler( + (value: number) => updateProgressBar(value), + { wait: 200 } +) + +// خطاف قائم على الإشارة (Signal) لإدارة الحالة +const [value, setValue, throttler] = createThrottledSignal(0, { + wait: 200, + onExecute: (throttler) => { + console.log('إجمالي عمليات التنفيذ:', throttler.getExecutionCount()) + } +}) +``` + +توفر كل أداة تكيف إطار خطاطيف تدمج مع نظام إدارة الحالة الخاص بالإطار مع الحفاظ على وظائف التحديد الأساسية. diff --git a/docs/ar/reference/classes/asyncdebouncer.md b/docs/ar/reference/classes/asyncdebouncer.md index 6f2231ad1..a8f777366 100644 --- a/docs/ar/reference/classes/asyncdebouncer.md +++ b/docs/ar/reference/classes/asyncdebouncer.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:20:00.343Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:02:32.594Z' id: AsyncDebouncer title: AsyncDebouncer --- @@ -9,7 +9,7 @@ title: AsyncDebouncer # Class: AsyncDebouncer\ -Defined in: [async-debouncer.ts:73](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L73) +Defined in: [async-debouncer.ts:77](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L77) A class that creates an async debounced function. @@ -20,17 +20,21 @@ or input changes where you only want to execute the handler after the events hav Unlike throttling which allows execution at regular intervals, debouncing prevents any execution until the function stops being called for the specified delay period. +Unlike the non-async Debouncer, this async version supports returning values from the debounced function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the debounced function. + ## Example ```ts const asyncDebouncer = new AsyncDebouncer(async (value: string) => { - await searchAPI(value); + const results = await searchAPI(value); + return results; // Return value is preserved }, { wait: 500 }); // Called on each keystroke but only executes after 500ms of no typing -inputElement.addEventListener('input', () => { - asyncDebouncer.maybeExecute(inputElement.value); -}); +// Returns the API response directly +const results = await asyncDebouncer.maybeExecute(inputElement.value); ``` ## Type Parameters @@ -45,7 +49,7 @@ inputElement.addEventListener('input', () => { new AsyncDebouncer(fn, initialOptions): AsyncDebouncer ``` -Defined in: [async-debouncer.ts:86](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L86) +Defined in: [async-debouncer.ts:90](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L90) #### Parameters @@ -69,7 +73,7 @@ Defined in: [async-debouncer.ts:86](https://github.com/TanStack/pacer/blob/main/ cancel(): void ``` -Defined in: [async-debouncer.ts:195](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L195) +Defined in: [async-debouncer.ts:199](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L199) Cancels any pending execution or aborts any execution in progress @@ -85,7 +89,7 @@ Cancels any pending execution or aborts any execution in progress getErrorCount(): number ``` -Defined in: [async-debouncer.ts:224](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L224) +Defined in: [async-debouncer.ts:228](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L228) Returns the number of times the function has errored @@ -101,7 +105,7 @@ Returns the number of times the function has errored getIsExecuting(): boolean ``` -Defined in: [async-debouncer.ts:238](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L238) +Defined in: [async-debouncer.ts:242](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L242) Returns `true` if there is currently an execution in progress @@ -117,7 +121,7 @@ Returns `true` if there is currently an execution in progress getIsPending(): boolean ``` -Defined in: [async-debouncer.ts:231](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L231) +Defined in: [async-debouncer.ts:235](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L235) Returns `true` if there is a pending execution queued up for trailing execution @@ -133,7 +137,7 @@ Returns `true` if there is a pending execution queued up for trailing execution getLastResult(): undefined | ReturnType ``` -Defined in: [async-debouncer.ts:203](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L203) +Defined in: [async-debouncer.ts:207](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L207) Returns the last result of the debounced function @@ -149,7 +153,7 @@ Returns the last result of the debounced function getOptions(): Required> ``` -Defined in: [async-debouncer.ts:112](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L112) +Defined in: [async-debouncer.ts:116](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L116) Returns the current debouncer options @@ -165,7 +169,7 @@ Returns the current debouncer options getSettleCount(): number ``` -Defined in: [async-debouncer.ts:217](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L217) +Defined in: [async-debouncer.ts:221](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L221) Returns the number of times the function has settled (completed or errored) @@ -181,7 +185,7 @@ Returns the number of times the function has settled (completed or errored) getSuccessCount(): number ``` -Defined in: [async-debouncer.ts:210](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L210) +Defined in: [async-debouncer.ts:214](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L214) Returns the number of times the function has been executed successfully @@ -197,7 +201,7 @@ Returns the number of times the function has been executed successfully maybeExecute(...args): Promise> ``` -Defined in: [async-debouncer.ts:120](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L120) +Defined in: [async-debouncer.ts:124](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L124) Attempts to execute the debounced function If a call is already in progress, it will be queued @@ -220,7 +224,7 @@ If a call is already in progress, it will be queued setOptions(newOptions): void ``` -Defined in: [async-debouncer.ts:100](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L100) +Defined in: [async-debouncer.ts:104](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L104) Updates the debouncer options Returns the new options state diff --git a/docs/ar/reference/classes/asyncratelimiter.md b/docs/ar/reference/classes/asyncratelimiter.md index 5a24714af..f96766e14 100644 --- a/docs/ar/reference/classes/asyncratelimiter.md +++ b/docs/ar/reference/classes/asyncratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:20:00.334Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:02:32.590Z' id: AsyncRateLimiter title: AsyncRateLimiter --- @@ -9,7 +9,7 @@ title: AsyncRateLimiter # Class: AsyncRateLimiter\ -Defined in: [async-rate-limiter.ts:76](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L76) +Defined in: [async-rate-limiter.ts:95](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L95) A class that creates an async rate-limited function. @@ -17,6 +17,16 @@ Rate limiting is a simple approach that allows a function to execute up to a lim then blocks all subsequent calls until the window passes. This can lead to "bursty" behavior where all executions happen immediately, followed by a complete block. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + +Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + For smoother execution patterns, consider using: - Throttling: Ensures consistent spacing between executions (e.g. max once per 200ms) - Debouncing: Waits for a pause in calls before executing (e.g. after 500ms of no calls) @@ -29,11 +39,12 @@ smoothing out frequent events, throttling or debouncing usually provide better u ```ts const rateLimiter = new AsyncRateLimiter( async (id: string) => await api.getData(id), - { limit: 5, window: 1000 } // 5 calls per second + { limit: 5, window: 1000, windowType: 'sliding' } // 5 calls per second with sliding window ); // Will execute immediately until limit reached, then block -await rateLimiter.maybeExecute('123'); +// Returns the API response directly +const data = await rateLimiter.maybeExecute('123'); ``` ## Type Parameters @@ -48,7 +59,7 @@ await rateLimiter.maybeExecute('123'); new AsyncRateLimiter(fn, initialOptions): AsyncRateLimiter ``` -Defined in: [async-rate-limiter.ts:85](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L85) +Defined in: [async-rate-limiter.ts:105](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L105) #### Parameters @@ -72,7 +83,7 @@ Defined in: [async-rate-limiter.ts:85](https://github.com/TanStack/pacer/blob/ma getErrorCount(): number ``` -Defined in: [async-rate-limiter.ts:209](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L209) +Defined in: [async-rate-limiter.ts:250](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L250) Returns the number of times the function has errored @@ -82,15 +93,33 @@ Returns the number of times the function has errored *** +### getIsExecuting() + +```ts +getIsExecuting(): boolean +``` + +Defined in: [async-rate-limiter.ts:264](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L264) + +Returns whether the function is currently executing + +#### Returns + +`boolean` + +*** + ### getMsUntilNextWindow() ```ts getMsUntilNextWindow(): number ``` -Defined in: [async-rate-limiter.ts:188](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L188) +Defined in: [async-rate-limiter.ts:225](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L225) Returns the number of milliseconds until the next execution will be possible +For fixed windows, this is the time until the current window resets +For sliding windows, this is the time until the oldest execution expires #### Returns @@ -104,7 +133,7 @@ Returns the number of milliseconds until the next execution will be possible getOptions(): Required> ``` -Defined in: [async-rate-limiter.ts:106](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L106) +Defined in: [async-rate-limiter.ts:126](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L126) Returns the current rate limiter options @@ -120,7 +149,7 @@ Returns the current rate limiter options getRejectionCount(): number ``` -Defined in: [async-rate-limiter.ts:216](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L216) +Defined in: [async-rate-limiter.ts:257](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L257) Returns the number of times the function has been rejected @@ -136,7 +165,7 @@ Returns the number of times the function has been rejected getRemainingInWindow(): number ``` -Defined in: [async-rate-limiter.ts:180](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L180) +Defined in: [async-rate-limiter.ts:215](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L215) Returns the number of remaining executions allowed in the current window @@ -152,7 +181,7 @@ Returns the number of remaining executions allowed in the current window getSettleCount(): number ``` -Defined in: [async-rate-limiter.ts:202](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L202) +Defined in: [async-rate-limiter.ts:243](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L243) Returns the number of times the function has been settled @@ -168,7 +197,7 @@ Returns the number of times the function has been settled getSuccessCount(): number ``` -Defined in: [async-rate-limiter.ts:195](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L195) +Defined in: [async-rate-limiter.ts:236](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L236) Returns the number of times the function has been executed @@ -184,7 +213,7 @@ Returns the number of times the function has been executed maybeExecute(...args): Promise> ``` -Defined in: [async-rate-limiter.ts:126](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L126) +Defined in: [async-rate-limiter.ts:146](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L146) Attempts to execute the rate-limited function if within the configured limits. Will reject execution if the number of calls in the current window exceeds the limit. @@ -220,7 +249,7 @@ await rateLimiter.maybeExecute('arg1', 'arg2'); // Rejected reset(): void ``` -Defined in: [async-rate-limiter.ts:223](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L223) +Defined in: [async-rate-limiter.ts:271](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L271) Resets the rate limiter state @@ -236,7 +265,7 @@ Resets the rate limiter state setOptions(newOptions): void ``` -Defined in: [async-rate-limiter.ts:99](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L99) +Defined in: [async-rate-limiter.ts:119](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L119) Updates the rate limiter options Returns the new options state diff --git a/docs/ar/reference/classes/asyncthrottler.md b/docs/ar/reference/classes/asyncthrottler.md index 182ae6311..4cc5dd88b 100644 --- a/docs/ar/reference/classes/asyncthrottler.md +++ b/docs/ar/reference/classes/asyncthrottler.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:20:00.330Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:02:32.586Z' id: AsyncThrottler title: AsyncThrottler --- @@ -9,7 +9,7 @@ title: AsyncThrottler # Class: AsyncThrottler\ -Defined in: [async-throttler.ts:76](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L76) +Defined in: [async-throttler.ts:80](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L80) A class that creates an async throttled function. @@ -17,6 +17,10 @@ Throttling limits how often a function can be executed, allowing only one execut Unlike debouncing which resets the delay timer on each call, throttling ensures the function executes at a regular interval regardless of how often it's called. +Unlike the non-async Throttler, this async version supports returning values from the throttled function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the throttled function. + This is useful for rate-limiting API calls, handling scroll/resize events, or any scenario where you want to ensure a maximum execution frequency. @@ -24,13 +28,13 @@ ensure a maximum execution frequency. ```ts const throttler = new AsyncThrottler(async (value: string) => { - await saveToAPI(value); + const result = await saveToAPI(value); + return result; // Return value is preserved }, { wait: 1000 }); // Will only execute once per second no matter how often called -inputElement.addEventListener('input', () => { - throttler.maybeExecute(inputElement.value); -}); +// Returns the API response directly +const result = await throttler.maybeExecute(inputElement.value); ``` ## Type Parameters @@ -45,7 +49,7 @@ inputElement.addEventListener('input', () => { new AsyncThrottler(fn, initialOptions): AsyncThrottler ``` -Defined in: [async-throttler.ts:89](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L89) +Defined in: [async-throttler.ts:93](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L93) #### Parameters @@ -69,7 +73,7 @@ Defined in: [async-throttler.ts:89](https://github.com/TanStack/pacer/blob/main/ cancel(): void ``` -Defined in: [async-throttler.ts:187](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L187) +Defined in: [async-throttler.ts:191](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L191) Cancels any pending execution or aborts any execution in progress @@ -85,7 +89,7 @@ Cancels any pending execution or aborts any execution in progress getErrorCount(): number ``` -Defined in: [async-throttler.ts:237](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L237) +Defined in: [async-throttler.ts:241](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L241) Returns the number of times the function has errored @@ -101,7 +105,7 @@ Returns the number of times the function has errored getIsExecuting(): boolean ``` -Defined in: [async-throttler.ts:251](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L251) +Defined in: [async-throttler.ts:255](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L255) Returns the current executing state @@ -117,7 +121,7 @@ Returns the current executing state getIsPending(): boolean ``` -Defined in: [async-throttler.ts:244](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L244) +Defined in: [async-throttler.ts:248](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L248) Returns the current pending state @@ -133,7 +137,7 @@ Returns the current pending state getLastExecutionTime(): number ``` -Defined in: [async-throttler.ts:202](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L202) +Defined in: [async-throttler.ts:206](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L206) Returns the last execution time @@ -149,7 +153,7 @@ Returns the last execution time getLastResult(): undefined | ReturnType ``` -Defined in: [async-throttler.ts:216](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L216) +Defined in: [async-throttler.ts:220](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L220) Returns the last result of the debounced function @@ -165,7 +169,7 @@ Returns the last result of the debounced function getNextExecutionTime(): number ``` -Defined in: [async-throttler.ts:209](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L209) +Defined in: [async-throttler.ts:213](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L213) Returns the next execution time @@ -181,7 +185,7 @@ Returns the next execution time getOptions(): Required> ``` -Defined in: [async-throttler.ts:115](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L115) +Defined in: [async-throttler.ts:119](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L119) Returns the current options @@ -197,7 +201,7 @@ Returns the current options getSettleCount(): number ``` -Defined in: [async-throttler.ts:230](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L230) +Defined in: [async-throttler.ts:234](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L234) Returns the number of times the function has settled (completed or errored) @@ -213,7 +217,7 @@ Returns the number of times the function has settled (completed or errored) getSuccessCount(): number ``` -Defined in: [async-throttler.ts:223](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L223) +Defined in: [async-throttler.ts:227](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L227) Returns the number of times the function has been executed successfully @@ -229,7 +233,7 @@ Returns the number of times the function has been executed successfully maybeExecute(...args): Promise> ``` -Defined in: [async-throttler.ts:123](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L123) +Defined in: [async-throttler.ts:127](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L127) Attempts to execute the throttled function If a call is already in progress, it may be blocked or queued depending on the `wait` option @@ -252,7 +256,7 @@ If a call is already in progress, it may be blocked or queued depending on the ` setOptions(newOptions): void ``` -Defined in: [async-throttler.ts:103](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L103) +Defined in: [async-throttler.ts:107](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L107) Updates the throttler options Returns the new options state diff --git a/docs/ar/reference/classes/ratelimiter.md b/docs/ar/reference/classes/ratelimiter.md index eba2c2c2f..c39d4bf99 100644 --- a/docs/ar/reference/classes/ratelimiter.md +++ b/docs/ar/reference/classes/ratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:20:00.317Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:02:32.576Z' id: RateLimiter title: RateLimiter --- @@ -9,7 +9,7 @@ title: RateLimiter # Class: RateLimiter\ -Defined in: [rate-limiter.ts:63](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L63) +Defined in: [rate-limiter.ts:77](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L77) A class that creates a rate-limited function. @@ -17,6 +17,12 @@ Rate limiting is a simple approach that allows a function to execute up to a lim then blocks all subsequent calls until the window passes. This can lead to "bursty" behavior where all executions happen immediately, followed by a complete block. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns, consider using: - Throttling: Ensures consistent spacing between executions (e.g. max once per 200ms) - Debouncing: Waits for a pause in calls before executing (e.g. after 500ms of no calls) @@ -29,7 +35,7 @@ smoothing out frequent events, throttling or debouncing usually provide better u ```ts const rateLimiter = new RateLimiter( (id: string) => api.getData(id), - { limit: 5, window: 1000 } // 5 calls per second + { limit: 5, window: 1000, windowType: 'sliding' } // 5 calls per second with sliding window ); // Will execute immediately until limit reached, then block @@ -48,7 +54,7 @@ rateLimiter.maybeExecute('123'); new RateLimiter(fn, initialOptions): RateLimiter ``` -Defined in: [rate-limiter.ts:69](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L69) +Defined in: [rate-limiter.ts:83](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L83) #### Parameters @@ -72,7 +78,7 @@ Defined in: [rate-limiter.ts:69](https://github.com/TanStack/pacer/blob/main/pac getExecutionCount(): number ``` -Defined in: [rate-limiter.ts:149](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L149) +Defined in: [rate-limiter.ts:175](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L175) Returns the number of times the function has been executed @@ -88,7 +94,7 @@ Returns the number of times the function has been executed getMsUntilNextWindow(): number ``` -Defined in: [rate-limiter.ts:171](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L171) +Defined in: [rate-limiter.ts:197](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L197) Returns the number of milliseconds until the next execution will be possible @@ -104,7 +110,7 @@ Returns the number of milliseconds until the next execution will be possible getOptions(): Required> ``` -Defined in: [rate-limiter.ts:90](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L90) +Defined in: [rate-limiter.ts:104](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L104) Returns the current rate limiter options @@ -120,7 +126,7 @@ Returns the current rate limiter options getRejectionCount(): number ``` -Defined in: [rate-limiter.ts:156](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L156) +Defined in: [rate-limiter.ts:182](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L182) Returns the number of times the function has been rejected @@ -136,7 +142,7 @@ Returns the number of times the function has been rejected getRemainingInWindow(): number ``` -Defined in: [rate-limiter.ts:163](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L163) +Defined in: [rate-limiter.ts:189](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L189) Returns the number of remaining executions allowed in the current window @@ -152,7 +158,7 @@ Returns the number of remaining executions allowed in the current window maybeExecute(...args): boolean ``` -Defined in: [rate-limiter.ts:109](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L109) +Defined in: [rate-limiter.ts:123](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L123) Attempts to execute the rate-limited function if within the configured limits. Will reject execution if the number of calls in the current window exceeds the limit. @@ -187,7 +193,7 @@ rateLimiter.maybeExecute('arg1', 'arg2'); // false reset(): void ``` -Defined in: [rate-limiter.ts:179](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L179) +Defined in: [rate-limiter.ts:208](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L208) Resets the rate limiter state @@ -203,7 +209,7 @@ Resets the rate limiter state setOptions(newOptions): void ``` -Defined in: [rate-limiter.ts:83](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L83) +Defined in: [rate-limiter.ts:97](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L97) Updates the rate limiter options Returns the new options state diff --git a/docs/ar/reference/functions/asyncdebounce.md b/docs/ar/reference/functions/asyncdebounce.md index ff6d98d0f..288095744 100644 --- a/docs/ar/reference/functions/asyncdebounce.md +++ b/docs/ar/reference/functions/asyncdebounce.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-04-24T02:14:56.000Z' -translation-updated-at: '2025-05-06T20:44:41.576Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:02:32.572Z' id: asyncDebounce title: asyncDebounce --- @@ -10,21 +10,23 @@ title: asyncDebounce # Function: asyncDebounce() ```ts -function asyncDebounce(fn, initialOptions): (...args) => Promise +function asyncDebounce(fn, initialOptions): (...args) => Promise> ``` -Defined in: [async-debouncer.ts:219](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L219) +Defined in: [async-debouncer.ts:268](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L268) Creates an async debounced function that delays execution until after a specified wait time. The debounced function will only execute once the wait period has elapsed without any new calls. If called again during the wait period, the timer resets and a new wait period begins. +Unlike the non-async Debouncer, this async version supports returning values from the debounced function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the debounced function. + ## Type Parameters • **TFn** *extends* [`AnyAsyncFunction`](../type-aliases/anyasyncfunction.md) -• **TArgs** *extends* `any`[] - ## Parameters ### fn @@ -33,7 +35,7 @@ If called again during the wait period, the timer resets and a new wait period b ### initialOptions -`Omit`\<[`AsyncDebouncerOptions`](../interfaces/asyncdebounceroptions.md)\<`TFn`, `TArgs`\>, `"enabled"`\> +`Omit`\<[`AsyncDebouncerOptions`](../interfaces/asyncdebounceroptions.md)\<`TFn`\>, `"enabled"`\> ## Returns @@ -46,21 +48,21 @@ If a call is already in progress, it will be queued #### args -...`TArgs` +...`Parameters`\<`TFn`\> ### Returns -`Promise`\<`void`\> +`Promise`\<`undefined` \| `ReturnType`\<`TFn`\>\> ## Example ```ts const debounced = asyncDebounce(async (value: string) => { - await saveToAPI(value); + const result = await saveToAPI(value); + return result; // Return value is preserved }, { wait: 1000 }); // Will only execute once, 1 second after the last call -await debounced("first"); // Cancelled -await debounced("second"); // Cancelled -await debounced("third"); // Executes after 1s +// Returns the API response directly +const result = await debounced("third"); ``` diff --git a/docs/ar/reference/functions/asyncratelimit.md b/docs/ar/reference/functions/asyncratelimit.md index 2c76dd282..8fd17c92d 100644 --- a/docs/ar/reference/functions/asyncratelimit.md +++ b/docs/ar/reference/functions/asyncratelimit.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:20:00.304Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:02:32.568Z' id: asyncRateLimit title: asyncRateLimit --- @@ -13,10 +13,20 @@ title: asyncRateLimit function asyncRateLimit(fn, initialOptions): (...args) => Promise> ``` -Defined in: [async-rate-limiter.ts:262](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L262) +Defined in: [async-rate-limiter.ts:322](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L322) Creates an async rate-limited function that will execute the provided function up to a maximum number of times within a time window. +Unlike the non-async rate limiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + Note that rate limiting is a simpler form of execution control compared to throttling or debouncing: - A rate limiter will allow all executions until the limit is reached, then block all subsequent calls until the window resets - A throttler ensures even spacing between executions, which can be better for consistent performance @@ -72,10 +82,11 @@ await rateLimiter.maybeExecute('arg1', 'arg2'); // Rejected ## Example ```ts -// Rate limit to 5 calls per minute +// Rate limit to 5 calls per minute with a sliding window const rateLimited = asyncRateLimit(makeApiCall, { limit: 5, window: 60000, + windowType: 'sliding', onReject: (rateLimiter) => { console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } @@ -83,7 +94,8 @@ const rateLimited = asyncRateLimit(makeApiCall, { // First 5 calls will execute immediately // Additional calls will be rejected until the minute window resets -await rateLimited(); +// Returns the API response directly +const result = await rateLimited(); // For more even execution, consider using throttle instead: const throttled = throttle(makeApiCall, { wait: 12000 }); // One call every 12 seconds diff --git a/docs/ar/reference/functions/asyncthrottle.md b/docs/ar/reference/functions/asyncthrottle.md index bf5ee9a7d..f7a4bc6a5 100644 --- a/docs/ar/reference/functions/asyncthrottle.md +++ b/docs/ar/reference/functions/asyncthrottle.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-04-24T02:14:56.000Z' -translation-updated-at: '2025-05-06T20:44:41.568Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:02:32.565Z' id: asyncThrottle title: asyncThrottle --- @@ -10,21 +10,23 @@ title: asyncThrottle # Function: asyncThrottle() ```ts -function asyncThrottle(fn, initialOptions): (...args) => Promise +function asyncThrottle(fn, initialOptions): (...args) => Promise> ``` -Defined in: [async-throttler.ts:223](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L223) +Defined in: [async-throttler.ts:281](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L281) Creates an async throttled function that limits how often the function can execute. The throttled function will execute at most once per wait period, even if called multiple times. If called while executing, it will wait until execution completes before scheduling the next call. +Unlike the non-async Throttler, this async version supports returning values from the throttled function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the throttled function. + ## Type Parameters • **TFn** *extends* [`AnyAsyncFunction`](../type-aliases/anyasyncfunction.md) -• **TArgs** *extends* `any`[] - ## Parameters ### fn @@ -33,7 +35,7 @@ If called while executing, it will wait until execution completes before schedul ### initialOptions -`Omit`\<[`AsyncThrottlerOptions`](../interfaces/asyncthrottleroptions.md)\<`TFn`, `TArgs`\>, `"enabled"`\> +`Omit`\<[`AsyncThrottlerOptions`](../interfaces/asyncthrottleroptions.md)\<`TFn`\>, `"enabled"`\> ## Returns @@ -46,20 +48,21 @@ If a call is already in progress, it may be blocked or queued depending on the ` #### args -...`TArgs` +...`Parameters`\<`TFn`\> ### Returns -`Promise`\<`void`\> +`Promise`\<`undefined` \| `ReturnType`\<`TFn`\>\> ## Example ```ts -const throttled = asyncThrottle(async () => { - await someAsyncOperation(); +const throttled = asyncThrottle(async (value: string) => { + const result = await saveToAPI(value); + return result; // Return value is preserved }, { wait: 1000 }); // This will execute at most once per second -await throttled(); -await throttled(); // Waits 1 second before executing +// Returns the API response directly +const result = await throttled(inputElement.value); ``` diff --git a/docs/ar/reference/functions/ratelimit.md b/docs/ar/reference/functions/ratelimit.md index b4b43fb98..e8be9cf37 100644 --- a/docs/ar/reference/functions/ratelimit.md +++ b/docs/ar/reference/functions/ratelimit.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:20:00.300Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:02:32.561Z' id: rateLimit title: rateLimit --- @@ -13,7 +13,7 @@ title: rateLimit function rateLimit(fn, initialOptions): (...args) => boolean ``` -Defined in: [rate-limiter.ts:216](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L216) +Defined in: [rate-limiter.ts:252](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L252) Creates a rate-limited function that will execute the provided function up to a maximum number of times within a time window. @@ -22,6 +22,12 @@ Note that rate limiting is a simpler form of execution control compared to throt - A throttler ensures even spacing between executions, which can be better for consistent performance - A debouncer collapses multiple calls into one, which is better for handling bursts of events +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + Consider using throttle() or debounce() if you need more intelligent execution control. Use rate limiting when you specifically need to enforce a hard limit on the number of executions within a time period. @@ -71,10 +77,11 @@ rateLimiter.maybeExecute('arg1', 'arg2'); // false ## Example ```ts -// Rate limit to 5 calls per minute +// Rate limit to 5 calls per minute with a sliding window const rateLimited = rateLimit(makeApiCall, { limit: 5, window: 60000, + windowType: 'sliding', onReject: (rateLimiter) => { console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/ar/reference/interfaces/asyncratelimiteroptions.md b/docs/ar/reference/interfaces/asyncratelimiteroptions.md index 76e7eb9a6..6c6343e41 100644 --- a/docs/ar/reference/interfaces/asyncratelimiteroptions.md +++ b/docs/ar/reference/interfaces/asyncratelimiteroptions.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:20:00.281Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:02:32.557Z' id: AsyncRateLimiterOptions title: AsyncRateLimiterOptions --- @@ -149,3 +149,18 @@ window: number; Defined in: [async-rate-limiter.ts:38](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L38) Time window in milliseconds within which the limit applies + +*** + +### windowType? + +```ts +optional windowType: "fixed" | "sliding"; +``` + +Defined in: [async-rate-limiter.ts:45](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L45) + +Type of window to use for rate limiting +- 'fixed': Uses a fixed window that resets after the window period +- 'sliding': Uses a sliding window that allows executions as old ones expire +Defaults to 'fixed' diff --git a/docs/ar/reference/interfaces/ratelimiteroptions.md b/docs/ar/reference/interfaces/ratelimiteroptions.md index 15f83ffad..89abae381 100644 --- a/docs/ar/reference/interfaces/ratelimiteroptions.md +++ b/docs/ar/reference/interfaces/ratelimiteroptions.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:20:00.241Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:02:32.553Z' id: RateLimiterOptions title: RateLimiterOptions --- @@ -97,3 +97,18 @@ window: number; Defined in: [rate-limiter.ts:27](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L27) Time window in milliseconds within which the limit applies + +*** + +### windowType? + +```ts +optional windowType: "fixed" | "sliding"; +``` + +Defined in: [rate-limiter.ts:34](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L34) + +Type of window to use for rate limiting +- 'fixed': Uses a fixed window that resets after the window period +- 'sliding': Uses a sliding window that allows executions as old ones expire +Defaults to 'fixed' diff --git a/docs/de/framework/react/reference/functions/useasyncratelimiter.md b/docs/de/framework/react/reference/functions/useasyncratelimiter.md index 8b69a832a..4711c6a2d 100644 --- a/docs/de/framework/react/reference/functions/useasyncratelimiter.md +++ b/docs/de/framework/react/reference/functions/useasyncratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:12:04.647Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:53:43.269Z' id: useAsyncRateLimiter title: useAsyncRateLimiter --- @@ -13,7 +13,7 @@ title: useAsyncRateLimiter function useAsyncRateLimiter(fn, options): AsyncRateLimiter ``` -Defined in: [react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts:43](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts#L43) +Defined in: [react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts:54](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts#L54) A low-level React hook that creates an `AsyncRateLimiter` instance to limit how many times an async function can execute within a time window. @@ -24,6 +24,16 @@ Rate limiting allows an async function to execute up to a specified limit within then blocks subsequent calls until the window passes. This is useful for respecting API rate limits, managing resource constraints, or controlling bursts of async operations. +Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + ## Type Parameters • **TFn** *extends* `AnyAsyncFunction` @@ -45,21 +55,22 @@ managing resource constraints, or controlling bursts of async operations. ## Example ```tsx -// Basic API call rate limiting +// Basic API call rate limiting with return value const { maybeExecute } = useAsyncRateLimiter( async (id: string) => { const data = await api.fetchData(id); - return data; + return data; // Return value is preserved }, { limit: 5, window: 1000 } // 5 calls per second ); -// With state management +// With state management and return value const [data, setData] = useState(null); const { maybeExecute } = useAsyncRateLimiter( async (query) => { const result = await searchAPI(query); setData(result); + return result; // Return value can be used by the caller }, { limit: 10, diff --git a/docs/de/framework/react/reference/functions/useratelimitedcallback.md b/docs/de/framework/react/reference/functions/useratelimitedcallback.md index 54bcb5bd2..94b1d7961 100644 --- a/docs/de/framework/react/reference/functions/useratelimitedcallback.md +++ b/docs/de/framework/react/reference/functions/useratelimitedcallback.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-04-24T02:14:56.000Z' -translation-updated-at: '2025-05-06T20:42:13.884Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:53:43.265Z' id: useRateLimitedCallback title: useRateLimitedCallback --- @@ -13,7 +13,7 @@ title: useRateLimitedCallback function useRateLimitedCallback(fn, options): (...args) => boolean ``` -Defined in: [rate-limiter/useRateLimitedCallback.ts:52](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedCallback.ts#L52) +Defined in: [react-pacer/src/rate-limiter/useRateLimitedCallback.ts:59](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedCallback.ts#L59) A React hook that creates a rate-limited version of a callback function. This hook is essentially a wrapper around the basic `rateLimiter` function @@ -26,6 +26,12 @@ or debouncing, it does not attempt to space out or intelligently collapse calls. This can lead to bursts of rapid executions followed by periods where all calls are blocked. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns, consider: - useThrottledCallback: When you want consistent spacing between executions (e.g. UI updates) - useDebouncedCallback: When you want to collapse rapid calls into a single execution (e.g. search input) @@ -57,7 +63,7 @@ Consider using the `useRateLimiter` hook instead. ### options -`RateLimiterOptions`\<`TFn`, `TArgs`\> +`RateLimiterOptions`\<`TFn`\> ## Returns @@ -76,7 +82,7 @@ Consider using the `useRateLimiter` hook instead. ## Example ```tsx -// Rate limit API calls to maximum 5 calls per minute +// Rate limit API calls to maximum 5 calls per minute with a sliding window const makeApiCall = useRateLimitedCallback( (data: ApiData) => { return fetch('/api/endpoint', { method: 'POST', body: JSON.stringify(data) }); @@ -84,6 +90,7 @@ const makeApiCall = useRateLimitedCallback( { limit: 5, window: 60000, // 1 minute + windowType: 'sliding', onReject: () => { console.warn('API rate limit reached. Please wait before trying again.'); } diff --git a/docs/de/framework/react/reference/functions/useratelimitedstate.md b/docs/de/framework/react/reference/functions/useratelimitedstate.md index 3346d579a..1f36a82eb 100644 --- a/docs/de/framework/react/reference/functions/useratelimitedstate.md +++ b/docs/de/framework/react/reference/functions/useratelimitedstate.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:12:04.610Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:53:43.262Z' id: useRateLimitedState title: useRateLimitedState --- @@ -13,7 +13,7 @@ title: useRateLimitedState function useRateLimitedState(value, options): [TValue, Dispatch>, RateLimiter>>] ``` -Defined in: [react-pacer/src/rate-limiter/useRateLimitedState.ts:59](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedState.ts#L59) +Defined in: [react-pacer/src/rate-limiter/useRateLimitedState.ts:66](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedState.ts#L66) A React hook that creates a rate-limited state value that enforces a hard limit on state updates within a time window. This hook combines React's useState with rate limiting functionality to provide controlled state updates. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - useThrottledState: When you want consistent spacing between updates (e.g. UI changes) - useDebouncedState: When you want to collapse rapid updates into a single update (e.g. search input) @@ -57,16 +63,18 @@ consider using the lower-level useRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update state at most 5 times per minute +// Basic rate limiting - update state at most 5 times per minute with a sliding window const [value, setValue, rateLimiter] = useRateLimitedState(0, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); -// With rejection callback +// With rejection callback and fixed window const [value, setValue] = useRateLimitedState(0, { limit: 3, window: 5000, + windowType: 'fixed', onReject: (rateLimiter) => { alert(`Rate limit reached. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/de/framework/react/reference/functions/useratelimitedvalue.md b/docs/de/framework/react/reference/functions/useratelimitedvalue.md index 8cd11b53a..f9058259a 100644 --- a/docs/de/framework/react/reference/functions/useratelimitedvalue.md +++ b/docs/de/framework/react/reference/functions/useratelimitedvalue.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:12:04.606Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:53:43.257Z' id: useRateLimitedValue title: useRateLimitedValue --- @@ -13,7 +13,7 @@ title: useRateLimitedValue function useRateLimitedValue(value, options): [TValue, RateLimiter>>] ``` -Defined in: [react-pacer/src/rate-limiter/useRateLimitedValue.ts:47](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedValue.ts#L47) +Defined in: [react-pacer/src/rate-limiter/useRateLimitedValue.ts:55](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedValue.ts#L55) A high-level React hook that creates a rate-limited version of a value that updates at most a certain number of times within a time window. This hook uses React's useState internally to manage the rate-limited state. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - useThrottledValue: When you want consistent spacing between updates (e.g. UI changes) - useDebouncedValue: When you want to collapse rapid updates into a single update (e.g. search input) @@ -56,16 +62,18 @@ consider using the lower-level useRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update at most 5 times per minute +// Basic rate limiting - update at most 5 times per minute with a sliding window const [rateLimitedValue, rateLimiter] = useRateLimitedValue(rawValue, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); -// With rejection callback +// With rejection callback and fixed window const [rateLimitedValue, rateLimiter] = useRateLimitedValue(rawValue, { limit: 3, window: 5000, + windowType: 'fixed', onReject: (rateLimiter) => { console.log(`Update rejected. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/de/framework/react/reference/functions/useratelimiter.md b/docs/de/framework/react/reference/functions/useratelimiter.md index 7cb7e799e..c3d93e437 100644 --- a/docs/de/framework/react/reference/functions/useratelimiter.md +++ b/docs/de/framework/react/reference/functions/useratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:12:04.602Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:53:43.254Z' id: useRateLimiter title: useRateLimiter --- @@ -13,7 +13,7 @@ title: useRateLimiter function useRateLimiter(fn, options): RateLimiter ``` -Defined in: [react-pacer/src/rate-limiter/useRateLimiter.ts:48](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimiter.ts#L48) +Defined in: [react-pacer/src/rate-limiter/useRateLimiter.ts:55](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimiter.ts#L55) A low-level React hook that creates a `RateLimiter` instance to enforce rate limits on function execution. @@ -24,6 +24,12 @@ Rate limiting is a simple "hard limit" approach that allows executions until a m a time window, then blocks all subsequent calls until the window resets. Unlike throttling or debouncing, it does not attempt to space out or collapse executions intelligently. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns: - Use throttling when you want consistent spacing between executions (e.g. UI updates) - Use debouncing when you want to collapse rapid-fire events (e.g. search input) @@ -57,10 +63,11 @@ The hook returns an object containing: ## Example ```tsx -// Basic rate limiting - max 5 calls per minute +// Basic rate limiting - max 5 calls per minute with a sliding window const { maybeExecute } = useRateLimiter(apiCall, { limit: 5, window: 60000, + windowType: 'sliding', }); // Monitor rate limit status diff --git a/docs/de/framework/solid/reference/functions/createasyncratelimiter.md b/docs/de/framework/solid/reference/functions/createasyncratelimiter.md index 6092b5663..bdd95e6d5 100644 --- a/docs/de/framework/solid/reference/functions/createasyncratelimiter.md +++ b/docs/de/framework/solid/reference/functions/createasyncratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:12:04.574Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:53:43.248Z' id: createAsyncRateLimiter title: createAsyncRateLimiter --- @@ -13,7 +13,7 @@ title: createAsyncRateLimiter function createAsyncRateLimiter(fn, initialOptions): SolidAsyncRateLimiter ``` -Defined in: [async-rate-limiter/createAsyncRateLimiter.ts:62](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L62) +Defined in: [async-rate-limiter/createAsyncRateLimiter.ts:73](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L73) A low-level Solid hook that creates an `AsyncRateLimiter` instance to limit how many times an async function can execute within a time window. @@ -24,6 +24,16 @@ Rate limiting allows an async function to execute up to a specified limit within then blocks subsequent calls until the window passes. This is useful for respecting API rate limits, managing resource constraints, or controlling bursts of async operations. +Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + ## Type Parameters • **TFn** *extends* `AnyAsyncFunction` @@ -45,21 +55,22 @@ managing resource constraints, or controlling bursts of async operations. ## Example ```tsx -// Basic API call rate limiting +// Basic API call rate limiting with return value const { maybeExecute } = createAsyncRateLimiter( async (id: string) => { const data = await api.fetchData(id); - return data; + return data; // Return value is preserved }, { limit: 5, window: 1000 } // 5 calls per second ); -// With state management +// With state management and return value const [data, setData] = createSignal(null); const { maybeExecute } = createAsyncRateLimiter( async (query) => { const result = await searchAPI(query); setData(result); + return result; // Return value can be used by the caller }, { limit: 10, diff --git a/docs/de/framework/solid/reference/functions/createratelimitedsignal.md b/docs/de/framework/solid/reference/functions/createratelimitedsignal.md index 731626e7d..649adb101 100644 --- a/docs/de/framework/solid/reference/functions/createratelimitedsignal.md +++ b/docs/de/framework/solid/reference/functions/createratelimitedsignal.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:12:04.549Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:53:43.244Z' id: createRateLimitedSignal title: createRateLimitedSignal --- @@ -13,7 +13,7 @@ title: createRateLimitedSignal function createRateLimitedSignal(value, initialOptions): [Accessor, Setter, SolidRateLimiter>] ``` -Defined in: [rate-limiter/createRateLimitedSignal.ts:57](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedSignal.ts#L57) +Defined in: [rate-limiter/createRateLimitedSignal.ts:65](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedSignal.ts#L65) A Solid hook that creates a rate-limited state value that enforces a hard limit on state updates within a time window. This hook combines Solid's createSignal with rate limiting functionality to provide controlled state updates. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - createThrottledSignal: When you want consistent spacing between updates (e.g. UI changes) - createDebouncedSignal: When you want to collapse rapid updates into a single update (e.g. search input) @@ -57,16 +63,18 @@ consider using the lower-level createRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update state at most 5 times per minute +// Basic rate limiting - update state at most 5 times per minute with a sliding window const [value, setValue, rateLimiter] = createRateLimitedSignal(0, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); -// With rejection callback +// With rejection callback and fixed window const [value, setValue] = createRateLimitedSignal(0, { limit: 3, window: 5000, + windowType: 'fixed', onReject: (rateLimiter) => { alert(`Rate limit reached. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/de/framework/solid/reference/functions/createratelimitedvalue.md b/docs/de/framework/solid/reference/functions/createratelimitedvalue.md index 8e7c29e51..719adb303 100644 --- a/docs/de/framework/solid/reference/functions/createratelimitedvalue.md +++ b/docs/de/framework/solid/reference/functions/createratelimitedvalue.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:12:04.544Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:53:43.241Z' id: createRateLimitedValue title: createRateLimitedValue --- @@ -13,7 +13,7 @@ title: createRateLimitedValue function createRateLimitedValue(value, initialOptions): [Accessor, SolidRateLimiter>] ``` -Defined in: [rate-limiter/createRateLimitedValue.ts:43](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedValue.ts#L43) +Defined in: [rate-limiter/createRateLimitedValue.ts:50](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedValue.ts#L50) A high-level Solid hook that creates a rate-limited version of a value that updates at most a certain number of times within a time window. This hook uses Solid's createSignal internally to manage the rate-limited state. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - createThrottledValue: When you want consistent spacing between updates (e.g. UI changes) - createDebouncedValue: When you want to collapse rapid updates into a single update (e.g. search input) @@ -56,10 +62,11 @@ consider using the lower-level createRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update at most 5 times per minute +// Basic rate limiting - update at most 5 times per minute with a sliding window const [rateLimitedValue, rateLimiter] = createRateLimitedValue(rawValue, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); // Use the rate-limited value diff --git a/docs/de/framework/solid/reference/functions/createratelimiter.md b/docs/de/framework/solid/reference/functions/createratelimiter.md index e6d7a3f33..15e973ac3 100644 --- a/docs/de/framework/solid/reference/functions/createratelimiter.md +++ b/docs/de/framework/solid/reference/functions/createratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:12:04.540Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:53:43.237Z' id: createRateLimiter title: createRateLimiter --- @@ -13,7 +13,7 @@ title: createRateLimiter function createRateLimiter(fn, initialOptions): SolidRateLimiter ``` -Defined in: [rate-limiter/createRateLimiter.ts:61](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts#L61) +Defined in: [rate-limiter/createRateLimiter.ts:68](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts#L68) A low-level Solid hook that creates a `RateLimiter` instance to enforce rate limits on function execution. @@ -24,6 +24,12 @@ Rate limiting is a simple "hard limit" approach that allows executions until a m a time window, then blocks all subsequent calls until the window resets. Unlike throttling or debouncing, it does not attempt to space out or collapse executions intelligently. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns: - Use throttling when you want consistent spacing between executions (e.g. UI updates) - Use debouncing when you want to collapse rapid-fire events (e.g. search input) @@ -50,10 +56,11 @@ For smoother execution patterns: ## Example ```tsx -// Basic rate limiting - max 5 calls per minute +// Basic rate limiting - max 5 calls per minute with a sliding window const rateLimiter = createRateLimiter(apiCall, { limit: 5, window: 60000, + windowType: 'sliding' }); // Monitor rate limit status diff --git a/docs/de/guides/debouncing.md b/docs/de/guides/debouncing.md index 166782ad2..3ebfcf56c 100644 --- a/docs/de/guides/debouncing.md +++ b/docs/de/guides/debouncing.md @@ -1,18 +1,18 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:14:40.500Z' -title: Debouncing-Anleitung +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:56:25.603Z' +title: Anleitung zu Debouncing id: debouncing --- -# Debouncing Guide (Anleitung zum Entprellen) +# Debouncing Guide (Leitfaden zum Entprellen) -Rate Limiting (Ratenbegrenzung), Throttling (Drosselung) und Debouncing (Entprellen) sind drei verschiedene Ansätze zur Steuerung der Ausführungsfrequenz von Funktionen. Jede Technik blockiert Ausführungen auf unterschiedliche Weise, wodurch sie "verlustbehaftet" sind - das bedeutet, dass einige Funktionsaufrufe nicht ausgeführt werden, wenn sie zu häufig angefordert werden. Das Verständnis, wann welcher Ansatz verwendet werden sollte, ist entscheidend für die Entwicklung performanter und zuverlässiger Anwendungen. Diese Anleitung behandelt die Debouncing-Konzepte von TanStack Pacer. +Rate Limiting (Ratenbegrenzung), Throttling (Drosselung) und Debouncing (Entprellen) sind drei verschiedene Ansätze zur Steuerung der Ausführungsfrequenz von Funktionen. Jede Technik blockiert Ausführungen auf unterschiedliche Weise, wodurch sie "verlustbehaftet" sind - das bedeutet, dass einige Funktionsaufrufe nicht ausgeführt werden, wenn sie zu häufig angefordert werden. Das Verständnis, wann welcher Ansatz verwendet werden sollte, ist entscheidend für die Entwicklung leistungsfähiger und zuverlässiger Anwendungen. Dieser Leitfaden behandelt die Debouncing-Konzepte von TanStack Pacer. -## Debouncing-Konzept +## Debouncing-Konzept (Debouncing Concept) -Debouncing (Entprellen) ist eine Technik, die die Ausführung einer Funktion verzögert, bis eine bestimmte Zeit der Inaktivität verstrichen ist. Im Gegensatz zur Ratenbegrenzung, die Ausführungen bis zu einem Limit erlaubt, oder zur Drosselung, die gleichmäßig verteilte Ausführungen gewährleistet, fasst Debouncing mehrere schnelle Funktionsaufrufe zu einer einzigen Ausführung zusammen, die erst nach dem Ende der Aufrufe erfolgt. Dies macht Debouncing ideal für die Handhabung von Ereignisausbrüchen, bei denen nur der Endzustand nach Abschluss der Aktivität relevant ist. +Debouncing ist eine Technik, die die Ausführung einer Funktion verzögert, bis eine bestimmte Phase der Inaktivität eingetreten ist. Im Gegensatz zur Ratenbegrenzung, die Ausführungen bis zu einem bestimmten Limit erlaubt, oder zur Drosselung, die gleichmäßig verteilte Ausführungen sicherstellt, fasst Debouncing mehrere schnelle Funktionsaufrufe zu einer einzigen Ausführung zusammen, die erst nach dem Ende der Aufrufe erfolgt. Dies macht Debouncing ideal für die Handhabung von Ereignisbursts, bei denen nur der Endzustand nach Abschluss der Aktivität relevant ist. -### Debouncing-Visualisierung +### Visuelle Darstellung des Debouncing (Debouncing Visualization) ```text Debouncing (wait: 3 ticks) @@ -23,33 +23,33 @@ Executed: ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ⏳ -> ✅ ❌ ^ Ausführung hier nach 3 Ticks ohne Aufrufe - [Aufrufausbruch] [Weitere Aufrufe] [Warten] [Neuer Ausbruch] - Keine Ausführung Setzt Timer zurück [Verzögerte Ausführung] [Warten] [Verzögerte Ausführung] + [Burst von Aufrufen] [Weitere Aufrufe] [Warten] [Neuer Burst] + Keine Ausführung Setzt Timer zurück [Verzögerte Ausführung] [Warten] [Verzögerte Ausführung] ``` -### Wann Debouncing verwendet werden sollte +### Wann Debouncing verwendet werden sollte (When to Use Debouncing) -Debouncing ist besonders effektiv, wenn Sie auf eine "Pause" in der Aktivität warten möchten, bevor Sie eine Aktion ausführen. Dies macht es ideal für die Handhabung von Benutzereingaben oder anderen schnell aufeinanderfolgenden Ereignissen, bei denen nur der Endzustand relevant ist. +Debouncing ist besonders effektiv, wenn Sie auf eine "Pause" in der Aktivität warten möchten, bevor Sie eine Aktion ausführen. Dies macht es ideal für die Handhabung von Benutzereingaben oder anderen schnell ausgelösten Ereignissen, bei denen nur der Endzustand relevant ist. Häufige Anwendungsfälle sind: - Suchfelder, bei denen gewartet werden soll, bis der Benutzer mit der Eingabe fertig ist - Formularvalidierung, die nicht bei jedem Tastendruck ausgeführt werden soll -- Fenstergrößenanpassungsberechnungen, die rechenintensiv sind +- Berechnungen bei Fenstergrößenänderungen, die rechenintensiv sind - Automatisches Speichern von Entwürfen während der Bearbeitung von Inhalten - API-Aufrufe, die erst nach Abschluss der Benutzeraktivität erfolgen sollen -- Jedes Szenario, in dem nur der Endwert nach schnellen Änderungen relevant ist +- Jedes Szenario, bei dem nur der Endwert nach schnellen Änderungen relevant ist -### Wann Debouncing nicht verwendet werden sollte +### Wann Debouncing nicht verwendet werden sollte (When Not to Use Debouncing) Debouncing ist möglicherweise nicht die beste Wahl, wenn: -- Sie eine garantierte Ausführung über einen bestimmten Zeitraum benötigen (verwenden Sie stattdessen [Throttling](../guides/throttling)) -- Sie es sich nicht leisten können, Ausführungen zu verpassen (verwenden Sie stattdessen [Queueing](../guides/queueing)) +- Sie eine garantierte Ausführung über einen bestimmten Zeitraum benötigen (verwenden Sie stattdessen [Drosselung](../guides/throttling)) +- Sie es sich nicht leisten können, Ausführungen zu verpassen (verwenden Sie stattdessen [Warteschlange](../guides/queueing)) -## Debouncing in TanStack Pacer +## Debouncing in TanStack Pacer (Debouncing in TanStack Pacer) TanStack Pacer bietet sowohl synchrones als auch asynchrones Debouncing über die Klassen `Debouncer` und `AsyncDebouncer` (und ihre entsprechenden Funktionen `debounce` und `asyncDebounce`). -### Grundlegende Verwendung mit `debounce` +### Grundlegende Verwendung mit `debounce` (Basic Usage with `debounce`) Die Funktion `debounce` ist die einfachste Möglichkeit, Debouncing zu einer beliebigen Funktion hinzuzufügen: @@ -69,7 +69,7 @@ searchInput.addEventListener('input', (e) => { }) ``` -### Erweiterte Verwendung mit der `Debouncer`-Klasse +### Erweiterte Verwendung mit der `Debouncer`-Klasse (Advanced Usage with `Debouncer` Class) Für mehr Kontrolle über das Debouncing-Verhalten können Sie die `Debouncer`-Klasse direkt verwenden: @@ -92,7 +92,7 @@ searchDebouncer.setOptions({ wait: 1000 }) // Wartezeit erhöhen searchDebouncer.cancel() ``` -### Führende und nachfolgende Ausführungen +### Führende und nachfolgende Ausführungen (Leading and Trailing Executions) Der synchrone Debouncer unterstützt sowohl führende als auch nachfolgende Ausführungen: @@ -114,20 +114,20 @@ Gängige Muster: - `{ leading: true, trailing: false }` - Sofortige Ausführung, nachfolgende Aufrufe ignorieren - `{ leading: true, trailing: true }` - Ausführung bei erstem Aufruf und nach Wartezeit -### Maximale Wartezeit +### Maximale Wartezeit (Max Wait Time) -Der TanStack Pacer Debouncer hat bewusst KEINE `maxWait`-Option wie andere Debouncing-Bibliotheken. Wenn Sie Ausführungen über einen längeren Zeitraum verteilen müssen, sollten Sie stattdessen die [Throttling](../guides/throttling)-Technik verwenden. +Der TanStack Pacer Debouncer hat bewusst KEINE `maxWait`-Option wie andere Debouncing-Bibliotheken. Wenn Sie Ausführungen über einen längeren Zeitraum verteilen müssen, sollten Sie stattdessen die [Drosselung](../guides/throttling)-Technik verwenden. -### Aktivieren/Deaktivieren +### Aktivieren/Deaktivieren (Enabling/Disabling) -Die `Debouncer`-Klasse unterstützt das Aktivieren/Deaktivieren über die Option `enabled`. Mit der Methode `setOptions` können Sie den Debouncer jederzeit aktivieren/deaktivieren: +Die `Debouncer`-Klasse unterstützt das Aktivieren/Deaktivieren über die `enabled`-Option. Mit der Methode `setOptions` können Sie den Debouncer jederzeit aktivieren/deaktivieren: ```ts const debouncer = new Debouncer(fn, { wait: 500, enabled: false }) // Standardmäßig deaktiviert debouncer.setOptions({ enabled: true }) // Jederzeit aktivieren ``` -Wenn Sie einen Framework-Adapter verwenden, bei dem die Debouncer-Optionen reaktiv sind, können Sie die Option `enabled` auf einen bedingten Wert setzen, um den Debouncer dynamisch zu aktivieren/deaktivieren: +Wenn Sie ein Framework-Adapter verwenden, bei dem die Debouncer-Optionen reaktiv sind, können Sie die `enabled`-Option auf einen bedingten Wert setzen, um den Debouncer dynamisch zu aktivieren/deaktivieren: ```ts // React-Beispiel @@ -137,7 +137,7 @@ const debouncer = useDebouncer( ) ``` -Wenn Sie jedoch die Funktion `debounce` oder die `Debouncer`-Klasse direkt verwenden, müssen Sie die Methode `setOptions` verwenden, um die Option `enabled` zu ändern, da die übergebenen Optionen tatsächlich an den Konstruktor der `Debouncer`-Klasse übergeben werden. +Wenn Sie jedoch die Funktion `debounce` oder die `Debouncer`-Klasse direkt verwenden, müssen Sie die Methode `setOptions` verwenden, um die `enabled`-Option zu ändern, da die übergebenen Optionen tatsächlich an den Konstruktor der `Debouncer`-Klasse übergeben werden. ```ts // Solid-Beispiel @@ -147,11 +147,11 @@ createEffect(() => { }) ``` -### Callback-Optionen +### Callback-Optionen (Callback Options) Sowohl der synchrone als auch der asynchrone Debouncer unterstützen Callback-Optionen zur Handhabung verschiedener Aspekte des Debouncing-Lebenszyklus: -#### Callbacks des synchronen Debouncers +#### Callbacks des synchronen Debouncers (Synchronous Debouncer Callbacks) Der synchrone `Debouncer` unterstützt folgenden Callback: @@ -167,9 +167,9 @@ const debouncer = new Debouncer(fn, { Der `onExecute`-Callback wird nach jeder erfolgreichen Ausführung der entprellten Funktion aufgerufen und ist nützlich für die Verfolgung von Ausführungen, die Aktualisierung des UI-Zustands oder Bereinigungsoperationen. -#### Callbacks des asynchronen Debouncers +#### Callbacks des asynchronen Debouncers (Asynchronous Debouncer Callbacks) -Der asynchrone `AsyncDebouncer` hat im Vergleich zur synchronen Version einen anderen Satz von Callbacks. +Der asynchrone `AsyncDebouncer` hat eine andere Reihe von Callbacks im Vergleich zur synchronen Version. ```ts const asyncDebouncer = new AsyncDebouncer(async (value) => { @@ -178,50 +178,44 @@ const asyncDebouncer = new AsyncDebouncer(async (value) => { wait: 500, onSuccess: (result, debouncer) => { // Wird nach jeder erfolgreichen Ausführung aufgerufen - console.log('Async-Funktion ausgeführt', debouncer.getSuccessCount()) + console.log('Asynchrone Funktion ausgeführt', debouncer.getSuccessCount()) }, onSettled: (debouncer) => { // Wird nach jedem Ausführungsversuch aufgerufen - console.log('Async-Funktion abgeschlossen', debouncer.getSettledCount()) + console.log('Asynchrone Funktion abgeschlossen', debouncer.getSettledCount()) }, onError: (error) => { - // Wird aufgerufen, wenn die Async-Funktion einen Fehler wirft - console.error('Async-Funktion fehlgeschlagen:', error) + // Wird aufgerufen, wenn die asynchrone Funktion einen Fehler wirft + console.error('Asynchrone Funktion fehlgeschlagen:', error) } }) ``` -Der `onSuccess`-Callback wird nach jeder erfolgreichen Ausführung der entprellten Funktion aufgerufen, während der `onError`-Callback aufgerufen wird, wenn die Async-Funktion einen Fehler wirft. Der `onSettled`-Callback wird nach jedem Ausführungsversuch aufgerufen, unabhängig von Erfolg oder Fehler. Diese Callbacks sind besonders nützlich für die Verfolgung von Ausführungszahlen, die Aktualisierung des UI-Zustands, die Fehlerbehandlung, Bereinigungsoperationen und die Protokollierung von Ausführungsmetriken. +Der `onSuccess`-Callback wird nach jeder erfolgreichen Ausführung der entprellten Funktion aufgerufen, während der `onError`-Callback aufgerufen wird, wenn die asynchrone Funktion einen Fehler wirft. Der `onSettled`-Callback wird nach jedem Ausführungsversuch aufgerufen, unabhängig von Erfolg oder Fehler. Diese Callbacks sind besonders nützlich für die Verfolgung von Ausführungszählern, die Aktualisierung des UI-Zustands, die Fehlerbehandlung, Bereinigungsoperationen und die Protokollierung von Ausführungsmetriken. -### Asynchrones Debouncing +### Asynchrones Debouncing (Asynchronous Debouncing) -Der asynchrone Debouncer bietet eine leistungsstarke Möglichkeit, asynchrone Operationen mit Debouncing zu handhaben und bietet mehrere wichtige Vorteile gegenüber der synchronen Version. Während der synchrone Debouncer ideal für UI-Ereignisse und sofortiges Feedback ist, ist die asynchrone Version speziell für die Handhabung von API-Aufrufen, Datenbankoperationen und anderen asynchronen Aufgaben konzipiert. +Der asynchrone Debouncer bietet eine leistungsstarke Möglichkeit, asynchrone Operationen mit Debouncing zu handhaben, und bietet mehrere wichtige Vorteile gegenüber der synchronen Version. Während der synchrone Debouncer ideal für UI-Ereignisse und sofortiges Feedback ist, ist die asynchrone Version speziell für die Handhabung von API-Aufrufen, Datenbankoperationen und anderen asynchronen Aufgaben konzipiert. -#### Wichtige Unterschiede zum synchronen Debouncing +#### Wichtige Unterschiede zum synchronen Debouncing (Key Differences from Synchronous Debouncing) 1. **Rückgabewertbehandlung** Im Gegensatz zum synchronen Debouncer, der void zurückgibt, ermöglicht die asynchrone Version die Erfassung und Verwendung des Rückgabewerts Ihrer entprellten Funktion. Dies ist besonders nützlich, wenn Sie mit den Ergebnissen von API-Aufrufen oder anderen asynchronen Operationen arbeiten müssen. Die Methode `maybeExecute` gibt ein Promise zurück, das mit dem Rückgabewert der Funktion aufgelöst wird, sodass Sie auf das Ergebnis warten und es entsprechend verarbeiten können. -2. **Erweitertes Callback-System** -Der asynchrone Debouncer bietet ein ausgefeilteres Callback-System im Vergleich zum einzelnen `onExecute`-Callback der synchronen Version. Dieses System umfasst: -- `onSuccess`: Wird aufgerufen, wenn die Async-Funktion erfolgreich abgeschlossen wird, mit Ergebnis und Debouncer-Instanz -- `onError`: Wird aufgerufen, wenn die Async-Funktion einen Fehler wirft, mit Fehler und Debouncer-Instanz -- `onSettled`: Wird nach jedem Ausführungsversuch aufgerufen, unabhängig von Erfolg oder Fehler +2. **Unterschiedliche Callbacks** +Der `AsyncDebouncer` unterstützt folgende Callbacks anstelle von nur `onExecute` in der synchronen Version: +- `onSuccess`: Wird nach jeder erfolgreichen Ausführung aufgerufen, mit der Debouncer-Instanz +- `onSettled`: Wird nach jeder Ausführung aufgerufen, mit der Debouncer-Instanz +- `onError`: Wird aufgerufen, wenn die asynchrone Funktion einen Fehler wirft, mit dem Fehler und der Debouncer-Instanz -3. **Ausführungsverfolgung** -Der asynchrone Debouncer bietet eine umfassende Ausführungsverfolgung durch mehrere Methoden: -- `getSuccessCount()`: Anzahl der erfolgreichen Ausführungen -- `getErrorCount()`: Anzahl der fehlgeschlagenen Ausführungen -- `getSettledCount()`: Gesamtzahl der abgeschlossenen Ausführungen (Erfolg + Fehler) +3. **Sequenzielle Ausführung** +Da die Methode `maybeExecute` des Debouncers ein Promise zurückgibt, können Sie wählen, ob Sie jede Ausführung abwarten möchten, bevor Sie die nächste starten. Dies gibt Ihnen Kontrolle über die Ausführungsreihenfolge und stellt sicher, dass jeder Aufruf die aktuellsten Daten verarbeitet. Dies ist besonders nützlich bei Operationen, die von den Ergebnissen vorheriger Aufrufe abhängen oder bei denen die Datenkonsistenz kritisch ist. -4. **Sequenzielle Ausführung** -Der asynchrone Debouncer stellt sicher, dass nachfolgende Ausführungen warten, bis der vorherige Aufruf abgeschlossen ist. Dies verhindert eine nicht sequenzielle Ausführung und garantiert, dass jeder Aufruf die aktuellsten Daten verarbeitet. Dies ist besonders wichtig, wenn Operationen von den Ergebnissen vorheriger Aufrufe abhängen oder die Datenkonsistenz kritisch ist. +Beispiel: Wenn Sie das Profil eines Benutzers aktualisieren und dann sofort seine aktualisierten Daten abrufen, können Sie auf den Abschluss der Aktualisierungsoperation warten, bevor Sie den Abruf starten: -Beispiel: Wenn Sie das Profil eines Benutzers aktualisieren und dann sofort dessen aktualisierte Daten abrufen, stellt der asynchrone Debouncer sicher, dass der Abrufvorgang auf die Aktualisierung wartet, wodurch Race Conditions verhindert werden, bei denen Sie möglicherweise veraltete Daten erhalten. +#### Grundlegendes Anwendungsbeispiel (Basic Usage Example) -#### Grundlegendes Anwendungsbeispiel - -Hier ein einfaches Beispiel für die Verwendung des asynchronen Debouncers für eine Suchoperation: +Hier ist ein grundlegendes Beispiel, das die Verwendung des asynchronen Debouncers für eine Suchoperation zeigt: ```ts const debouncedSearch = asyncDebounce( @@ -244,22 +238,9 @@ const debouncedSearch = asyncDebounce( const results = await debouncedSearch('query') ``` -#### Erweiterte Muster - -Der asynchrone Debouncer kann mit verschiedenen Mustern kombiniert werden, um komplexe Probleme zu lösen: - -1. **Integration der Zustandsverwaltung** -Bei der Verwendung des asynchronen Debouncers mit Zustandsverwaltungssystemen (wie Reacts useState oder Solids createSignal) können Sie leistungsstarke Muster für die Handhabung von Ladezuständen, Fehlerzuständen und Datenaktualisierungen erstellen. Die Callbacks des Debouncers bieten perfekte Hooks für die Aktualisierung des UI-Zustands basierend auf dem Erfolg oder Misserfolg von Operationen. - -2. **Verhinderung von Race Conditions** -Das Single-Flight-Mutation-Muster verhindert natürlicherweise Race Conditions in vielen Szenarien. Wenn mehrere Teile Ihrer Anwendung versuchen, dieselbe Ressource gleichzeitig zu aktualisieren, stellt der Debouncer sicher, dass nur die neueste Aktualisierung tatsächlich erfolgt, während dennoch Ergebnisse an alle Aufrufer zurückgegeben werden. - -3. **Fehlerbehebung** -Die Fehlerbehandlungsfähigkeiten des asynchronen Debouncers machen ihn ideal für die Implementierung von Wiederholungslogik und Fehlerbehebungsmustern. Sie können den `onError`-Callback verwenden, um benutzerdefinierte Fehlerbehandlungsstrategien wie exponentielles Backoff oder Fallback-Mechanismen zu implementieren. - -### Framework-Adapter +### Framework-Adapter (Framework Adapters) -Jeder Framework-Adapter bietet Hooks, die auf der Kern-Debouncing-Funktionalität aufbauen, um sich in das Zustandsverwaltungssystem des Frameworks zu integrieren. Für jedes Framework sind Hooks wie `createDebouncer`, `useDebouncedCallback`, `useDebouncedState` oder `useDebouncedValue` verfügbar. +Jeder Framework-Adapter bietet Hooks, die auf der Kern-Debouncing-Funktionalität aufbauen, um sich in das Zustandsmanagement-System des Frameworks zu integrieren. Hooks wie `createDebouncer`, `useDebouncedCallback`, `useDebouncedState` oder `useDebouncedValue` sind für jedes Framework verfügbar. Hier einige Beispiele: @@ -280,7 +261,7 @@ const handleSearch = useDebouncedCallback( { wait: 500 } ) -// Zustandsbasierter Hook für reaktive Zustandsverwaltung +// Zustandsbasierter Hook für reaktives Zustandsmanagement const [instantState, setInstantState] = useState('') const [debouncedValue] = useDebouncedValue( instantState, // Zu entprellender Wert @@ -299,7 +280,7 @@ const debouncer = createDebouncer( { wait: 500 } ) -// Signalbasierter Hook für Zustandsverwaltung +// Signalbasierter Hook für Zustandsmanagement const [searchTerm, setSearchTerm, debouncer] = createDebouncedSignal('', { wait: 500, onExecute: (debouncer) => { diff --git a/docs/de/guides/rate-limiting.md b/docs/de/guides/rate-limiting.md index 3a4c8ae4a..106a81833 100644 --- a/docs/de/guides/rate-limiting.md +++ b/docs/de/guides/rate-limiting.md @@ -1,19 +1,19 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:14:42.635Z' -title: Ratenbegrenzungs-Anleitung +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:56:39.060Z' +title: Anleitung zur Ratenbegrenzung id: rate-limiting --- # Rate Limiting Guide (Anleitung zur Ratenbegrenzung) -Rate Limiting (Ratenbegrenzung), Throttling (Drosselung) und Debouncing (Entprellung) sind drei verschiedene Ansätze zur Steuerung der Ausführungsfrequenz von Funktionen. Jede Technik blockiert Ausführungen auf unterschiedliche Weise, wodurch sie "verlustbehaftet" sind – das bedeutet, dass einige Funktionsaufrufe nicht ausgeführt werden, wenn sie zu häufig angefordert werden. Das Verständnis, wann welcher Ansatz anzuwenden ist, ist entscheidend für die Entwicklung performanter und zuverlässiger Anwendungen. Diese Anleitung behandelt die Rate-Limiting-Konzepte von TanStack Pacer. +Rate Limiting (Ratenbegrenzung), Throttling (Drosselung) und Debouncing (Entprellung) sind drei verschiedene Ansätze zur Steuerung der Ausführungsfrequenz von Funktionen. Jede Technik blockiert Ausführungen auf unterschiedliche Weise, wodurch sie "verlustbehaftet" sind – das bedeutet, dass einige Funktionsaufrufe nicht ausgeführt werden, wenn sie zu häufig angefordert werden. Das Verständnis, wann welcher Ansatz anzuwenden ist, ist entscheidend für die Entwicklung leistungsfähiger und zuverlässiger Anwendungen. Diese Anleitung behandelt die Rate-Limiting-Konzepte von TanStack Pacer. > [!NOTE] -> TanStack Pacer ist derzeit nur eine Frontend-Bibliothek. Dies sind Hilfsmittel für clientseitige Ratenbegrenzung. +> TanStack Pacer ist derzeit nur eine Front-End-Bibliothek. Dies sind Hilfsmittel für clientseitige Ratenbegrenzung. ## Konzept der Ratenbegrenzung -Rate Limiting (Ratenbegrenzung) ist eine Technik, die die Rate begrenzt, mit der eine Funktion innerhalb eines bestimmten Zeitfensters ausgeführt werden kann. Sie ist besonders nützlich für Szenarien, in denen verhindert werden soll, dass eine Funktion zu häufig aufgerufen wird, z. B. bei der Abwicklung von API-Anfragen oder anderen Aufrufen externer Dienste. Es ist der *einfachste* Ansatz, da er Ausführungen in Bursts erlaubt, bis das Kontingent erschöpft ist. +Rate Limiting ist eine Technik, die die Rate begrenzt, mit der eine Funktion innerhalb eines bestimmten Zeitfensters ausgeführt werden kann. Sie ist besonders nützlich für Szenarien, in denen verhindert werden soll, dass eine Funktion zu häufig aufgerufen wird, z. B. bei der Abwicklung von API-Anfragen oder anderen Aufrufen externer Dienste. Es handelt sich um den *naivsten* Ansatz, da er Ausführungen in Bursts erlaubt, bis das Kontingent erschöpft ist. ### Visualisierung der Ratenbegrenzung @@ -21,32 +21,61 @@ Rate Limiting (Ratenbegrenzung) ist eine Technik, die die Rate begrenzt, mit der Rate Limiting (limit: 3 calls per window) Timeline: [1 second per tick] Window 1 | Window 2 -Calls: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ �️ +Calls: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ Executed: ✅ ✅ ✅ ❌ ❌ ✅ ✅ [=== 3 allowed ===][=== blocked until window ends ===][=== new window =======] ``` +### Fenstertypen + +TanStack Pacer unterstützt zwei Arten von Ratenbegrenzungsfenstern: + +1. **Festes Fenster (Fixed Window)** (Standard) + - Ein strenges Fenster, das nach dem Fensterzeitraum zurückgesetzt wird + - Alle Ausführungen innerhalb des Fensters zählen zur Begrenzung + - Das Fenster wird nach dem Zeitraum vollständig zurückgesetzt + - Kann zu burstartigem Verhalten an den Fenstergrenzen führen + +2. **Gleitendes Fenster (Sliding Window)** + - Ein rollierendes Fenster, das Ausführungen zulässt, sobald ältere ablaufen + - Ermöglicht eine gleichmäßigere Ausführungsrate über die Zeit + - Besser geeignet, um einen stetigen Ausführungsfluss aufrechtzuerhalten + - Verhindert burstartiges Verhalten an den Fenstergrenzen + +Hier eine Visualisierung der Ratenbegrenzung mit gleitendem Fenster: + +```text +Sliding Window Rate Limiting (limit: 3 calls per window) +Timeline: [1 second per tick] + Window 1 | Window 2 +Calls: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ +Executed: ✅ ✅ ✅ ❌ ✅ ✅ ✅ + [=== 3 allowed ===][=== oldest expires, new allowed ===][=== continues sliding =======] +``` + +Der entscheidende Unterschied besteht darin, dass bei einem gleitenden Fenster eine neue Ausführung zugelassen wird, sobald die älteste Ausführung abläuft. Dies führt im Vergleich zum festen Fensteransatz zu einem gleichmäßigeren Ausführungsfluss. + ### Wann Ratenbegrenzung verwendet werden sollte -Rate Limiting (Ratenbegrenzung) ist besonders wichtig, wenn es um Frontend-Operationen geht, die versehentlich Backend-Dienste überlasten oder Leistungsprobleme im Browser verursachen könnten. +Rate Limiting ist besonders wichtig bei Front-End-Operationen, die versehentlich Ihre Back-End-Dienste überlasten oder Leistungsprobleme im Browser verursachen könnten. Häufige Anwendungsfälle sind: -- Verhinderung versehentlicher API-Spam durch schnelle Benutzerinteraktionen (z. B. Button-Klicks oder Formularübermittlungen) +- Verhindern von versehentlichem API-Spam durch schnelle Benutzerinteraktionen (z. B. Button-Klicks oder Formularübermittlungen) - Szenarien, in denen burstartiges Verhalten akzeptabel ist, aber die maximale Rate begrenzt werden soll - Schutz vor versehentlichen Endlosschleifen oder rekursiven Operationen ### Wann Ratenbegrenzung nicht verwendet werden sollte -Rate Limiting (Ratenbegrenzung) ist der einfachste Ansatz zur Steuerung der Ausführungsfrequenz von Funktionen. Es ist die unflexibelste und restriktivste der drei Techniken. Erwägen Sie stattdessen die Verwendung von [Throttling](../guides/throttling) oder [Debouncing](../guides/debouncing) für gleichmäßiger verteilte Ausführungen. +Rate Limiting ist der naivste Ansatz zur Steuerung der Ausführungsfrequenz von Funktionen. Es ist die unflexibelste und restriktivste der drei Techniken. Erwägen Sie stattdessen die Verwendung von [Throttling](../guides/throttling) oder [Debouncing](../guides/debouncing) für gleichmäßiger verteilte Ausführungen. > [!TIP] > In den meisten Fällen möchten Sie wahrscheinlich keine "Ratenbegrenzung" verwenden. Erwägen Sie stattdessen die Verwendung von [Throttling](../guides/throttling) oder [Debouncing](../guides/debouncing). -Die "verlustbehaftete" Natur der Ratenbegrenzung bedeutet auch, dass einige Ausführungen abgelehnt und verloren gehen. Dies kann ein Problem sein, wenn Sie sicherstellen müssen, dass alle Ausführungen immer erfolgreich sind. Erwägen Sie die Verwendung von [Queueing](../guides/queueing), wenn Sie sicherstellen müssen, dass alle Ausführungen in eine Warteschlange gestellt werden, um mit einer gedrosselten Verzögerung ausgeführt zu werden, um die Ausführungsrate zu verlangsamen. +Die "verlustbehaftete" Natur der Ratenbegrenzung bedeutet auch, dass einige Ausführungen abgelehnt und verloren gehen. Dies kann ein Problem sein, wenn Sie sicherstellen müssen, dass alle Ausführungen immer erfolgreich sind. Erwägen Sie die Verwendung von [Queueing](../guides/queueing), wenn Sie sicherstellen müssen, dass alle Ausführungen in die Warteschlange gestellt werden, um mit einer gedrosselten Verzögerung ausgeführt zu werden, die die Ausführungsrate verlangsamt. ## Ratenbegrenzung in TanStack Pacer -TanStack Pacer bietet sowohl synchrone als auch asynchrone Ratenbegrenzung über die Klassen `RateLimiter` und `AsyncRateLimiter` (und ihre entsprechenden Funktionen `rateLimit` und `asyncRateLimit`). +TanStack Pacer bietet sowohl synchrone als auch asynchrone Ratenbegrenzung über die Klassen `RateLimiter` bzw. `AsyncRateLimiter` (und die entsprechenden Funktionen `rateLimit` und `asyncRateLimit`). ### Grundlegende Verwendung mit `rateLimit` @@ -61,6 +90,7 @@ const rateLimitedApi = rateLimit( { limit: 5, window: 60 * 1000, // 1 Minute in Millisekunden + windowType: 'fixed', // Standard onReject: (rateLimiter) => { console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`) } @@ -103,7 +133,7 @@ console.log(limiter.getRemainingInWindow()) // Anzahl der verbleibenden Aufrufe console.log(limiter.getExecutionCount()) // Gesamtzahl der erfolgreichen Ausführungen console.log(limiter.getRejectionCount()) // Gesamtzahl der abgelehnten Ausführungen -// Versuch, auszuführen (gibt einen Boolean zurück, der den Erfolg anzeigt) +// Versuch einer Ausführung (gibt einen booleschen Wert zurück, der den Erfolg anzeigt) limiter.maybeExecute('user-1') // Optionen dynamisch aktualisieren @@ -115,7 +145,10 @@ limiter.reset() ### Aktivieren/Deaktivieren -Die `RateLimiter`-Klasse unterstützt das Aktivieren/Deaktivieren über die Option `enabled`. Mit der Methode `setOptions` können Sie den Rate-Limiter jederzeit aktivieren/deaktivieren: +Die `RateLimiter`-Klasse unterstützt das Aktivieren/Deaktivieren über die Option `enabled`. Mit der Methode `setOptions` können Sie den Rate Limiter jederzeit aktivieren/deaktivieren: + +> [!NOTE] +> Die Option `enabled` aktiviert/deaktiviert die tatsächliche Funktionsausführung. Das Deaktivieren des Rate Limiters schaltet die Ratenbegrenzung nicht aus, sondern verhindert lediglich die Ausführung der Funktion. ```ts const limiter = new RateLimiter(fn, { @@ -126,13 +159,13 @@ const limiter = new RateLimiter(fn, { limiter.setOptions({ enabled: true }) // Jederzeit aktivieren ``` -Wenn Sie ein Framework-Adapter verwenden, bei dem die Rate-Limiter-Optionen reaktiv sind, können Sie die Option `enabled` auf einen bedingten Wert setzen, um den Rate-Limiter dynamisch zu aktivieren/deaktivieren. Wenn Sie jedoch die Funktion `rateLimit` oder die `RateLimiter`-Klasse direkt verwenden, müssen Sie die Methode `setOptions` verwenden, um die Option `enabled` zu ändern, da die übergebenen Optionen tatsächlich an den Konstruktor der `RateLimiter`-Klasse übergeben werden. +Wenn Sie ein Framework-Adapter verwenden, bei dem die Rate-Limiter-Optionen reaktiv sind, können Sie die Option `enabled` auf einen bedingten Wert setzen, um den Rate Limiter dynamisch zu aktivieren/deaktivieren. Wenn Sie jedoch die Funktion `rateLimit` oder die Klasse `RateLimiter` direkt verwenden, müssen Sie die Methode `setOptions` verwenden, um die Option `enabled` zu ändern, da die übergebenen Optionen tatsächlich an den Konstruktor der `RateLimiter`-Klasse übergeben werden. ### Callback-Optionen -Sowohl die synchronen als auch die asynchronen Rate-Limiter unterstützen Callback-Optionen zur Behandlung verschiedener Aspekte des Ratenbegrenzungs-Lebenszyklus: +Sowohl die synchronen als auch die asynchronen Rate Limiter unterstützen Callback-Optionen zur Behandlung verschiedener Aspekte des Ratenbegrenzungs-Lebenszyklus: -#### Callbacks des synchronen Rate-Limiters +#### Callbacks des synchronen Rate Limiters Der synchrone `RateLimiter` unterstützt die folgenden Callbacks: @@ -151,9 +184,9 @@ const limiter = new RateLimiter(fn, { }) ``` -Der `onExecute`-Callback wird nach jeder erfolgreichen Ausführung der rate-limitierten Funktion aufgerufen, während der `onReject`-Callback aufgerufen wird, wenn eine Ausführung aufgrund der Ratenbegrenzung abgelehnt wird. Diese Callbacks sind nützlich für die Verfolgung von Ausführungen, die Aktualisierung des UI-Status oder die Bereitstellung von Feedback für Benutzer. +Der Callback `onExecute` wird nach jeder erfolgreichen Ausführung der rate-limited-Funktion aufgerufen, während der Callback `onReject` aufgerufen wird, wenn eine Ausführung aufgrund der Ratenbegrenzung abgelehnt wird. Diese Callbacks sind nützlich für die Verfolgung von Ausführungen, die Aktualisierung des UI-Status oder die Bereitstellung von Feedback für Benutzer. -#### Callbacks des asynchronen Rate-Limiters +#### Callbacks des asynchronen Rate Limiters Der asynchrone `AsyncRateLimiter` unterstützt zusätzliche Callbacks für die Fehlerbehandlung: @@ -178,38 +211,33 @@ const asyncLimiter = new AsyncRateLimiter(async (id) => { }) ``` -Die Callbacks `onExecute` und `onReject` funktionieren auf die gleiche Weise wie beim synchronen Rate-Limiter, während der `onError`-Callback es Ihnen ermöglicht, Fehler elegant zu behandeln, ohne die Ratenbegrenzungskette zu unterbrechen. Diese Callbacks sind besonders nützlich für die Verfolgung von Ausführungszählern, die Aktualisierung des UI-Status, die Fehlerbehandlung und die Bereitstellung von Feedback für Benutzer. +Die Callbacks `onExecute` und `onReject` funktionieren auf die gleiche Weise wie beim synchronen Rate Limiter, während der Callback `onError` es Ihnen ermöglicht, Fehler elegant zu behandeln, ohne die Ratenbegrenzungskette zu unterbrechen. Diese Callbacks sind besonders nützlich für die Verfolgung von Ausführungszählern, die Aktualisierung des UI-Status, die Fehlerbehandlung und die Bereitstellung von Feedback für Benutzer. ### Asynchrone Ratenbegrenzung -Der asynchrone Rate-Limiter bietet eine leistungsstarke Möglichkeit, asynchrone Operationen mit Ratenbegrenzung zu handhaben, und bietet mehrere entscheidende Vorteile gegenüber der synchronen Version. Während der synchrone Rate-Limiter ideal für UI-Ereignisse und sofortiges Feedback ist, ist die asynchrone Version speziell für die Handhabung von API-Aufrufen, Datenbankoperationen und anderen asynchronen Aufgaben konzipiert. +Der asynchrone Rate Limiter bietet eine leistungsstarke Möglichkeit, asynchrone Operationen mit Ratenbegrenzung zu handhaben, und bietet mehrere entscheidende Vorteile gegenüber der synchronen Version. Während der synchrone Rate Limiter ideal für UI-Ereignisse und sofortiges Feedback ist, ist die asynchrone Version speziell für die Handhabung von API-Aufrufen, Datenbankoperationen und anderen asynchronen Aufgaben konzipiert. #### Wichtige Unterschiede zur synchronen Ratenbegrenzung -1. **Handhabung von Rückgabewerten** -Im Gegensatz zum synchronen Rate-Limiter, der einen Boolean zurückgibt, der den Erfolg anzeigt, ermöglicht die asynchrone Version die Erfassung und Verwendung des Rückgabewerts Ihrer rate-limitierten Funktion. Dies ist besonders nützlich, wenn Sie mit den Ergebnissen von API-Aufrufen oder anderen asynchronen Operationen arbeiten müssen. Die Methode `maybeExecute` gibt ein Promise zurück, das mit dem Rückgabewert der Funktion aufgelöst wird, sodass Sie auf das Ergebnis warten und es entsprechend verarbeiten können. +1. **Behandlung von Rückgabewerten** +Im Gegensatz zum synchronen Rate Limiter, der einen booleschen Wert zurückgibt, der den Erfolg anzeigt, ermöglicht die asynchrone Version die Erfassung und Verwendung des Rückgabewerts Ihrer rate-limited-Funktion. Dies ist besonders nützlich, wenn Sie mit den Ergebnissen von API-Aufrufen oder anderen asynchronen Operationen arbeiten müssen. Die Methode `maybeExecute` gibt ein Promise zurück, das mit dem Rückgabewert der Funktion aufgelöst wird, sodass Sie das Ergebnis erwarten und entsprechend behandeln können. -2. **Erweitertes Callback-System** -Der asynchrone Rate-Limiter bietet ein ausgefeilteres Callback-System im Vergleich zu den Callbacks der synchronen Version. Dieses System umfasst: -- `onExecute`: Wird nach jeder erfolgreichen Ausführung aufgerufen und stellt die Rate-Limiter-Instanz bereit -- `onReject`: Wird aufgerufen, wenn eine Ausführung aufgrund der Ratenbegrenzung abgelehnt wird, und stellt die Rate-Limiter-Instanz bereit +2. **Unterschiedliche Callbacks** +Der `AsyncRateLimiter` unterstützt die folgenden Callbacks anstelle von nur `onExecute` in der synchronen Version: +- `onSuccess`: Wird nach jeder erfolgreichen Ausführung aufgerufen und stellt die Rate-Limiter-Instanz bereit +- `onSettled`: Wird nach jeder Ausführung aufgerufen und stellt die Rate-Limiter-Instanz bereit - `onError`: Wird aufgerufen, wenn die asynchrone Funktion einen Fehler wirft, und stellt sowohl den Fehler als auch die Rate-Limiter-Instanz bereit -3. **Ausführungsverfolgung** -Der asynchrone Rate-Limiter bietet eine umfassende Ausführungsverfolgung durch mehrere Methoden: -- `getExecutionCount()`: Anzahl der erfolgreichen Ausführungen -- `getRejectionCount()`: Anzahl der abgelehnten Ausführungen -- `getRemainingInWindow()`: Anzahl der verbleibenden Ausführungen im aktuellen Fenster -- `getMsUntilNextWindow()`: Millisekunden bis zum Start des nächsten Fensters +Sowohl die asynchronen als auch die synchronen Rate Limiter unterstützen den Callback `onReject` für die Behandlung blockierter Ausführungen. -4. **Sequenzielle Ausführung** -Der asynchrone Rate-Limiter stellt sicher, dass nachfolgende Ausführungen warten, bis der vorherige Aufruf abgeschlossen ist, bevor sie beginnen. Dies verhindert eine nicht sequenzielle Ausführung und garantiert, dass jeder Aufruf die aktuellsten Daten verarbeitet. Dies ist besonders wichtig, wenn es um Operationen geht, die von den Ergebnissen vorheriger Aufrufe abhängen oder wenn die Datenkonsistenz kritisch ist. +3. **Sequenzielle Ausführung** +Da die Methode `maybeExecute` des Rate Limiters ein Promise zurückgibt, können Sie wählen, ob Sie jede Ausführung abwarten möchten, bevor Sie die nächste starten. Dies gibt Ihnen Kontrolle über die Ausführungsreihenfolge und stellt sicher, dass jeder Aufruf die aktuellsten Daten verarbeitet. Dies ist besonders nützlich, wenn Sie mit Operationen arbeiten, die von den Ergebnissen vorheriger Aufrufe abhängen, oder wenn die Aufrechterhaltung der Datenkonsistenz kritisch ist. -Wenn Sie beispielsweise das Profil eines Benutzers aktualisieren und dann sofort dessen aktualisierte Daten abrufen, stellt der asynchrone Rate-Limiter sicher, dass der Abrufvorgang auf die Fertigstellung der Aktualisierung wartet, wodurch Race Conditions verhindert werden, bei denen Sie möglicherweise veraltete Daten erhalten. +Beispielsweise, wenn Sie das Profil eines Benutzers aktualisieren und dann sofort dessen aktualisierte Daten abrufen, können Sie die Aktualisierungsoperation abwarten, bevor Sie den Abruf starten: #### Grundlegendes Anwendungsbeispiel -Hier ist ein grundlegendes Beispiel, das zeigt, wie der asynchrone Rate-Limiter für eine API-Operation verwendet wird: +Hier ein grundlegendes Beispiel, das zeigt, wie der asynchrone Rate Limiter für eine API-Operation verwendet wird: ```ts const rateLimitedApi = asyncRateLimit( @@ -236,22 +264,9 @@ const rateLimitedApi = asyncRateLimit( const result = await rateLimitedApi('123') ``` -#### Erweiterte Muster - -Der asynchrone Rate-Limiter kann mit verschiedenen Mustern kombiniert werden, um komplexe Probleme zu lösen: - -1. **Integration der Zustandsverwaltung** -Wenn Sie den asynchronen Rate-Limiter mit Zustandsverwaltungssystemen (wie Reacts useState oder Solids createSignal) verwenden, können Sie leistungsstarke Muster für die Handhabung von Ladezuständen, Fehlerzuständen und Datenaktualisierungen erstellen. Die Callbacks des Rate-Limiters bieten perfekte Hooks für die Aktualisierung des UI-Status basierend auf dem Erfolg oder Misserfolg von Operationen. - -2. **Verhinderung von Race Conditions** -Das Ratenbegrenzungsmuster verhindert auf natürliche Weise Race Conditions in vielen Szenarien. Wenn mehrere Teile Ihrer Anwendung versuchen, dieselbe Ressource gleichzeitig zu aktualisieren, stellt der Rate-Limiter sicher, dass die Aktualisierungen innerhalb der konfigurierten Grenzen erfolgen, während dennoch Ergebnisse an alle Aufrufer zurückgegeben werden. - -3. **Fehlerbehebung** -Die Fehlerbehandlungsfähigkeiten des asynchronen Rate-Limiters machen ihn ideal für die Implementierung von Wiederholungslogik und Fehlerbehebungsmustern. Sie können den `onError`-Callback verwenden, um benutzerdefinierte Fehlerbehandlungsstrategien zu implementieren, wie z. B. exponentielles Backoff oder Fallback-Mechanismen. - ### Framework-Adapter -Jeder Framework-Adapter bietet Hooks, die auf der Kernfunktionalität der Ratenbegrenzung aufbauen, um sich in das Zustandsverwaltungssystem des Frameworks zu integrieren. Hooks wie `createRateLimiter`, `useRateLimitedCallback`, `useRateLimitedState` oder `useRateLimitedValue` sind für jedes Framework verfügbar. +Jeder Framework-Adapter bietet Hooks, die auf der Kernfunktionalität der Ratenbegrenzung aufbauen, um sich in das State-Management-System des Frameworks zu integrieren. Für jedes Framework sind Hooks wie `createRateLimiter`, `useRateLimitedCallback`, `useRateLimitedState` oder `useRateLimitedValue` verfügbar. Hier einige Beispiele: @@ -272,7 +287,7 @@ const handleFetch = useRateLimitedCallback( { limit: 5, window: 1000 } ) -// Zustandsbasierter Hook für reaktive Zustandsverwaltung +// State-basierter Hook für reaktives State-Management const [instantState, setInstantState] = useState('') const [rateLimitedValue] = useRateLimitedValue( instantState, // Zu begrenzender Wert @@ -283,4 +298,6 @@ const [rateLimitedValue] = useRateLimitedValue( #### Solid ```tsx -import { createRateLimiter, createRateLimitedSignal } from '@ +import { createRateLimiter, createRateLimitedSignal } from '@tanstack/solid-pacer' + +// Low-Level-Hook diff --git a/docs/de/guides/throttling.md b/docs/de/guides/throttling.md index 8610d6fbc..1c5f425ea 100644 --- a/docs/de/guides/throttling.md +++ b/docs/de/guides/throttling.md @@ -1,18 +1,18 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:14:29.456Z' -title: Throttling-Anleitung +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:56:10.559Z' +title: Anleitung zu Throttling id: throttling --- # Throttling Guide (Drosselungsleitfaden) -Rate Limiting (Ratenbegrenzung), Throttling (Drosselung) und Debouncing (Entprellung) sind drei verschiedene Ansätze zur Steuerung der Ausführungsfrequenz von Funktionen. Jede Technik blockiert Ausführungen auf unterschiedliche Weise, was sie "verlustbehaftet" macht - das bedeutet, dass einige Funktionsaufrufe nicht ausgeführt werden, wenn sie zu häufig angefordert werden. Das Verständnis, wann welcher Ansatz verwendet werden sollte, ist entscheidend für die Entwicklung leistungsfähiger und zuverlässiger Anwendungen. Dieser Leitfaden behandelt die Throttling-Konzepte von TanStack Pacer. +Rate Limiting (Ratenbegrenzung), Throttling (Drosselung) und Debouncing (Entprellung) sind drei verschiedene Ansätze zur Steuerung der Ausführungsfrequenz von Funktionen. Jede Technik blockiert Ausführungen auf unterschiedliche Weise, wodurch sie "verlustbehaftet" sind – das bedeutet, dass einige Funktionsaufrufe nicht ausgeführt werden, wenn sie zu häufig angefordert werden. Das Verständnis, wann welcher Ansatz verwendet werden sollte, ist entscheidend für die Entwicklung leistungsfähiger und zuverlässiger Anwendungen. Dieser Leitfaden behandelt die Throttling-Konzepte von TanStack Pacer. -## Throttling-Konzept (Drosselungskonzept) +## Throttling-Konzept -Throttling stellt sicher, dass Funktionsausführungen gleichmäßig über die Zeit verteilt sind. Im Gegensatz zur Ratenbegrenzung, die Ausführungsbursts bis zu einem Limit erlaubt, oder zur Entprellung, die auf das Ende der Aktivität wartet, erzeugt Throttling ein gleichmäßigeres Ausführungsmuster durch konsequente Verzögerungen zwischen den Aufrufen. Wenn Sie eine Drosselung von einer Ausführung pro Sekunde festlegen, werden die Aufrufe gleichmäßig verteilt, unabhängig davon, wie schnell sie angefordert werden. +Throttling stellt sicher, dass Funktionsausführungen gleichmäßig über die Zeit verteilt werden. Im Gegensatz zur Ratenbegrenzung, die Ausführungsbursts bis zu einem Limit erlaubt, oder zur Entprellung, die auf das Ende der Aktivität wartet, erzeugt Throttling ein gleichmäßigeres Ausführungsmuster durch konsequente Verzögerungen zwischen den Aufrufen. Wenn Sie eine Drosselung von einer Ausführung pro Sekunde festlegen, werden die Aufrufe gleichmäßig verteilt, unabhängig davon, wie schnell sie angefordert werden. -### Throttling-Visualisierung (Drosselungsvisualisierung) +### Throttling-Visualisierung ```text Throttling (one execution per 3 ticks) @@ -28,34 +28,34 @@ Executed: ✅ ❌ ⏳ -> ✅ ❌ ❌ ❌ ✅ ✅ dann drosseln Wartezeit Ablauf der Wartezeit ``` -### Wann Throttling verwenden +### Wann Throttling verwendet werden sollte Throttling ist besonders effektiv, wenn Sie konsistente, vorhersehbare Ausführungszeiten benötigen. Dies macht es ideal für die Handhabung häufiger Ereignisse oder Updates, bei denen Sie ein gleichmäßiges, kontrolliertes Verhalten wünschen. Häufige Anwendungsfälle sind: - UI-Updates, die konsistente Timing benötigen (z.B. Fortschrittsanzeigen) - Scroll- oder Resize-Event-Handler, die den Browser nicht überlasten sollten -- Echtzeit-Datenabfragen mit konsistenten Intervallen -- Ressourcenintensive Operationen mit gleichmäßiger Geschwindigkeit +- Echtzeit-Datenabfragen mit gewünschten konsistenten Intervallen +- Ressourcenintensive Operationen, die eine gleichmäßige Geschwindigkeit benötigen - Spielschleifen-Updates oder Animation Frame Handling - Live-Suchvorschläge während der Eingabe -### Wann Throttling nicht verwenden +### Wann Throttling nicht verwendet werden sollte Throttling ist möglicherweise nicht die beste Wahl, wenn: - Sie auf das Ende der Aktivität warten möchten (verwenden Sie stattdessen [Debouncing](../guides/debouncing)) -- Sie es sich nicht leisten können, Ausführungen zu verpassen (verwenden Sie stattdessen [Queueing](../guides/queueing)) +- Sie sich keine verpassten Ausführungen leisten können (verwenden Sie stattdessen [Queueing](../guides/queueing)) > [!TIP] -> Throttling ist oft die beste Wahl, wenn Sie gleichmäßige, konsistente Ausführungszeiten benötigen. Es bietet ein vorhersehbareres Ausführungsmuster als Ratenbegrenzung und unmittelbareres Feedback als Entprellung. +> Throttling ist oft die beste Wahl, wenn Sie ein gleichmäßiges, konsistentes Ausführungs-Timing benötigen. Es bietet ein vorhersehbareres Ausführungsmuster als Ratenbegrenzung und ein unmittelbareres Feedback als Entprellung. ## Throttling in TanStack Pacer -TanStack Pacer bietet sowohl synchrones als auch asynchrones Throttling durch die Klassen `Throttler` und `AsyncThrottler` (und ihre entsprechenden Funktionen `throttle` und `asyncThrottle`). +TanStack Pacer bietet sowohl synchrones als auch asynchrones Throttling durch die Klassen `Throttler` und `AsyncThrottler` (sowie deren entsprechende Funktionen `throttle` und `asyncThrottle`). ### Grundlegende Verwendung mit `throttle` -Die `throttle`-Funktion ist der einfachste Weg, um Throttling zu einer Funktion hinzuzufügen: +Die Funktion `throttle` ist der einfachste Weg, um Throttling zu einer Funktion hinzuzufügen: ```ts import { throttle } from '@tanstack/pacer' @@ -101,12 +101,12 @@ Der synchrone Throttler unterstützt sowohl führende als auch nachfolgende Ausf ```ts const throttledFn = throttle(fn, { wait: 200, - leading: true, // Sofort bei erstem Aufruf ausführen (Standard) - trailing: true, // Nach Wartezeit ausführen (Standard) + leading: true, // Sofortige Ausführung beim ersten Aufruf (Standard) + trailing: true, // Ausführung nach Wartezeit (Standard) }) ``` -- `leading: true` (Standard) - Sofort bei erstem Aufruf ausführen +- `leading: true` (Standard) - Sofortige Ausführung beim ersten Aufruf - `leading: false` - Ersten Aufruf überspringen, auf nachfolgende Ausführung warten - `trailing: true` (Standard) - Letzten Aufruf nach Wartezeit ausführen - `trailing: false` - Letzten Aufruf überspringen, wenn innerhalb der Wartezeit @@ -125,11 +125,11 @@ const throttler = new Throttler(fn, { wait: 200, enabled: false }) // Standardm throttler.setOptions({ enabled: true }) // Jederzeit aktivierbar ``` -Wenn Sie ein Framework-Adapter verwenden, bei dem die Throttler-Optionen reaktiv sind, können Sie die Option `enabled` auf einen bedingten Wert setzen, um den Throttler dynamisch zu aktivieren/deaktivieren. Wenn Sie jedoch die `throttle`-Funktion oder die `Throttler`-Klasse direkt verwenden, müssen Sie die Methode `setOptions` verwenden, um die `enabled`-Option zu ändern, da die übergebenen Optionen tatsächlich an den Konstruktor der `Throttler`-Klasse übergeben werden. +Wenn Sie ein Framework-Adapter verwenden, bei dem die Throttler-Optionen reaktiv sind, können Sie die Option `enabled` auf einen bedingten Wert setzen, um den Throttler dynamisch zu aktivieren/deaktivieren. Wenn Sie jedoch die Funktion `throttle` oder die `Throttler`-Klasse direkt verwenden, müssen Sie die Methode `setOptions` verwenden, um die `enabled`-Option zu ändern, da die übergebenen Optionen tatsächlich an den Konstruktor der `Throttler`-Klasse übergeben werden. ### Callback-Optionen -Sowohl die synchronen als auch die asynchronen Throttler unterstützen Callback-Optionen zur Handhabung verschiedener Aspekte des Throttling-Lebenszyklus: +Sowohl der synchrone als auch der asynchrone Throttler unterstützen Callback-Optionen zur Handhabung verschiedener Aspekte des Throttling-Lebenszyklus: #### Synchroner Throttler-Callbacks @@ -139,13 +139,13 @@ Der synchrone `Throttler` unterstützt folgenden Callback: const throttler = new Throttler(fn, { wait: 200, onExecute: (throttler) => { - // Nach jeder erfolgreichen Ausführung aufgerufen + // Wird nach jeder erfolgreichen Ausführung aufgerufen console.log('Funktion ausgeführt', throttler.getExecutionCount()) } }) ``` -Der `onExecute`-Callback wird nach jeder erfolgreichen Ausführung der gedrosselten Funktion aufgerufen, was ihn nützlich für die Verfolgung von Ausführungen, die Aktualisierung des UI-Zustands oder Bereinigungsoperationen macht. +Der `onExecute`-Callback wird nach jeder erfolgreichen Ausführung der gedrosselten Funktion aufgerufen und eignet sich somit für die Verfolgung von Ausführungen, die Aktualisierung des UI-Zustands oder Bereinigungsoperationen. #### Asynchrone Throttler-Callbacks @@ -157,17 +157,17 @@ const asyncThrottler = new AsyncThrottler(async (value) => { }, { wait: 200, onExecute: (throttler) => { - // Nach jeder erfolgreichen Ausführung aufgerufen + // Wird nach jeder erfolgreichen Ausführung aufgerufen console.log('Async-Funktion ausgeführt', throttler.getExecutionCount()) }, onError: (error) => { - // Bei Fehlern der Async-Funktion aufgerufen + // Wird aufgerufen, wenn die Async-Funktion einen Fehler wirft console.error('Async-Funktion fehlgeschlagen:', error) } }) ``` -Der `onExecute`-Callback funktioniert wie beim synchronen Throttler, während der `onError`-Callback eine elegante Fehlerbehandlung ohne Unterbrechung der Throttling-Kette ermöglicht. Diese Callbacks sind besonders nützlich für die Verfolgung von Ausführungszählern, UI-Zustandsaktualisierungen, Fehlerbehandlung, Bereinigungsoperationen und die Protokollierung von Ausführungsmetriken. +Der `onExecute`-Callback funktioniert genauso wie beim synchronen Throttler, während der `onError`-Callback eine elegante Fehlerbehandlung ohne Unterbrechung der Throttling-Kette ermöglicht. Diese Callbacks sind besonders nützlich für die Verfolgung von Ausführungszahlen, die Aktualisierung des UI-Zustands, die Fehlerbehandlung, Bereinigungsoperationen und die Protokollierung von Ausführungsmetriken. ### Asynchrones Throttling @@ -176,28 +176,24 @@ Der asynchrone Throttler bietet eine leistungsstarke Möglichkeit, asynchrone Op #### Wichtige Unterschiede zum synchronen Throttling 1. **Rückgabewertbehandlung** -Anders als der synchrone Throttler, der void zurückgibt, erlaubt die asynchrone Version die Erfassung und Verwendung des Rückgabewerts Ihrer gedrosselten Funktion. Dies ist besonders nützlich, wenn Sie mit Ergebnissen von API-Aufrufen oder anderen asynchronen Operationen arbeiten müssen. Die Methode `maybeExecute` gibt ein Promise zurück, das mit dem Rückgabewert der Funktion aufgelöst wird, sodass Sie auf das Ergebnis warten und es entsprechend verarbeiten können. +Anders als der synchrone Throttler, der void zurückgibt, ermöglicht die asynchrone Version die Erfassung und Nutzung des Rückgabewerts Ihrer gedrosselten Funktion. Dies ist besonders nützlich, wenn Sie mit Ergebnissen von API-Aufrufen oder anderen asynchronen Operationen arbeiten müssen. Die Methode `maybeExecute` gibt ein Promise zurück, das mit dem Rückgabewert der Funktion aufgelöst wird, sodass Sie auf das Ergebnis warten und es entsprechend verarbeiten können. -2. **Erweitertes Callback-System** -Der asynchrone Throttler bietet ein ausgefeilteres Callback-System im Vergleich zum einzelnen `onExecute`-Callback der synchronen Version. Dieses System umfasst: -- `onSuccess`: Wird aufgerufen, wenn die Async-Funktion erfolgreich abgeschlossen wird, mit Ergebnis und Throttler-Instanz -- `onError`: Wird bei Fehlern der Async-Funktion aufgerufen, mit Fehler und Throttler-Instanz -- `onSettled`: Wird nach jedem Ausführungsversuch aufgerufen, unabhängig von Erfolg oder Misserfolg +2. **Unterschiedliche Callbacks** +Der `AsyncThrottler` unterstützt folgende Callbacks anstelle von nur `onExecute` in der synchronen Version: +- `onSuccess`: Wird nach jeder erfolgreichen Ausführung aufgerufen, mit der Throttler-Instanz +- `onSettled`: Wird nach jeder Ausführung aufgerufen, mit der Throttler-Instanz +- `onError`: Wird aufgerufen, wenn die Async-Funktion einen Fehler wirft, mit dem Fehler und der Throttler-Instanz -3. **Ausführungsverfolgung** -Der asynchrone Throttler bietet umfassende Ausführungsverfolgung durch mehrere Methoden: -- `getSuccessCount()`: Anzahl erfolgreicher Ausführungen -- `getErrorCount()`: Anzahl fehlgeschlagener Ausführungen -- `getSettledCount()`: Gesamtanzahl abgeschlossener Ausführungen (Erfolg + Fehler) +Sowohl der asynchrone als auch der synchrone Throttler unterstützen den `onExecute`-Callback für die Handhabung erfolgreicher Ausführungen. -4. **Sequenzielle Ausführung** -Der asynchrone Throttler stellt sicher, dass nachfolgende Ausführungen auf den Abschluss des vorherigen Aufrufs warten. Dies verhindert Out-of-Order-Ausführungen und garantiert, dass jeder Aufruf die aktuellsten Daten verarbeitet. Dies ist besonders wichtig bei Operationen, die von den Ergebnissen vorheriger Aufrufe abhängen oder bei denen die Datenkonsistenz kritisch ist. +3. **Sequenzielle Ausführung** +Da die Methode `maybeExecute` des Throttlers ein Promise zurückgibt, können Sie wählen, ob Sie jede Ausführung abwarten möchten, bevor Sie die nächste starten. Dies gibt Ihnen Kontrolle über die Ausführungsreihenfolge und stellt sicher, dass jeder Aufruf die aktuellsten Daten verarbeitet. Dies ist besonders nützlich bei Operationen, die von den Ergebnissen vorheriger Aufrufe abhängen oder bei denen die Datenkonsistenz kritisch ist. -Zum Beispiel, wenn Sie ein Benutzerprofil aktualisieren und dann sofort die aktualisierten Daten abrufen, sorgt der asynchrone Throttler dafür, dass der Abrufvorgang auf den Abschluss der Aktualisierung wartet, wodurch Race Conditions vermieden werden, bei denen Sie veraltete Daten erhalten könnten. +Zum Beispiel, wenn Sie das Profil eines Benutzers aktualisieren und dann sofort die aktualisierten Daten abrufen, können Sie die Update-Operation abwarten, bevor Sie den Abruf starten: #### Grundlegendes Anwendungsbeispiel -Hier ein einfaches Beispiel für die Verwendung des asynchronen Throttlers für eine Suchoperation: +Hier ein grundlegendes Beispiel für die Verwendung des asynchronen Throttlers für eine Suchoperation: ```ts const throttledSearch = asyncThrottle( @@ -220,22 +216,9 @@ const throttledSearch = asyncThrottle( const results = await throttledSearch('query') ``` -#### Erweiterte Muster - -Der asynchrone Throttler kann mit verschiedenen Mustern kombiniert werden, um komplexe Probleme zu lösen: - -1. **Integration mit State Management** -Bei der Verwendung des asynchronen Throttlers mit State-Management-Systemen (wie Reacts useState oder Solids createSignal) können Sie leistungsstarke Muster für die Handhabung von Ladezuständen, Fehlerzuständen und Datenaktualisierungen erstellen. Die Callbacks des Throttlers bieten ideale Hooks für die Aktualisierung des UI-Zustands basierend auf dem Erfolg oder Misserfolg von Operationen. - -2. **Race Condition-Prävention** -Das Throttling-Muster verhindert natürlicherweise Race Conditions in vielen Szenarien. Wenn mehrere Teile Ihrer Anwendung versuchen, dieselbe Ressource gleichzeitig zu aktualisieren, stellt der Throttler sicher, dass Aktualisierungen mit kontrollierter Rate erfolgen, während Ergebnisse trotzdem an alle Aufrufer zurückgegeben werden. - -3. **Fehlerbehebung** -Die Fehlerbehandlungsfähigkeiten des asynchronen Throttlers machen ihn ideal für die Implementierung von Wiederholungslogik und Fehlerbehebungsmustern. Sie können den `onError`-Callback verwenden, um benutzerdefinierte Fehlerbehandlungsstrategien wie exponentielles Backoff oder Fallback-Mechanismen zu implementieren. - ### Framework-Adapter -Jeder Framework-Adapter bietet Hooks, die auf der Kern-Throttling-Funktionalität aufbauen und sich in das State-Management-System des Frameworks integrieren. Hooks wie `createThrottler`, `useThrottledCallback`, `useThrottledState` oder `useThrottledValue` sind für jedes Framework verfügbar. +Jeder Framework-Adapter bietet Hooks, die auf der grundlegenden Throttling-Funktionalität aufbauen und sich in das State-Management-System des Frameworks integrieren. Hooks wie `createThrottler`, `useThrottledCallback`, `useThrottledState` oder `useThrottledValue` sind für jedes Framework verfügbar. Hier einige Beispiele: @@ -284,4 +267,4 @@ const [value, setValue, throttler] = createThrottledSignal(0, { }) ``` -Jeder Framework-Adapter bietet Hooks, die sich in das State-Management-System des Frameworks integrieren, während die Kern-Throttling-Funktionalität erhalten bleibt. +Jeder Framework-Adapter bietet Hooks, die sich in das State-Management-System des Frameworks integrieren, während die grundlegende Throttling-Funktionalität erhalten bleibt. diff --git a/docs/de/reference/classes/asyncdebouncer.md b/docs/de/reference/classes/asyncdebouncer.md index a89a60887..4c4c3ed43 100644 --- a/docs/de/reference/classes/asyncdebouncer.md +++ b/docs/de/reference/classes/asyncdebouncer.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:12:04.508Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:53:43.233Z' id: AsyncDebouncer title: AsyncDebouncer --- @@ -9,7 +9,7 @@ title: AsyncDebouncer # Class: AsyncDebouncer\ -Defined in: [async-debouncer.ts:73](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L73) +Defined in: [async-debouncer.ts:77](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L77) A class that creates an async debounced function. @@ -20,17 +20,21 @@ or input changes where you only want to execute the handler after the events hav Unlike throttling which allows execution at regular intervals, debouncing prevents any execution until the function stops being called for the specified delay period. +Unlike the non-async Debouncer, this async version supports returning values from the debounced function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the debounced function. + ## Example ```ts const asyncDebouncer = new AsyncDebouncer(async (value: string) => { - await searchAPI(value); + const results = await searchAPI(value); + return results; // Return value is preserved }, { wait: 500 }); // Called on each keystroke but only executes after 500ms of no typing -inputElement.addEventListener('input', () => { - asyncDebouncer.maybeExecute(inputElement.value); -}); +// Returns the API response directly +const results = await asyncDebouncer.maybeExecute(inputElement.value); ``` ## Type Parameters @@ -45,7 +49,7 @@ inputElement.addEventListener('input', () => { new AsyncDebouncer(fn, initialOptions): AsyncDebouncer ``` -Defined in: [async-debouncer.ts:86](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L86) +Defined in: [async-debouncer.ts:90](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L90) #### Parameters @@ -69,7 +73,7 @@ Defined in: [async-debouncer.ts:86](https://github.com/TanStack/pacer/blob/main/ cancel(): void ``` -Defined in: [async-debouncer.ts:195](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L195) +Defined in: [async-debouncer.ts:199](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L199) Cancels any pending execution or aborts any execution in progress @@ -85,7 +89,7 @@ Cancels any pending execution or aborts any execution in progress getErrorCount(): number ``` -Defined in: [async-debouncer.ts:224](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L224) +Defined in: [async-debouncer.ts:228](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L228) Returns the number of times the function has errored @@ -101,7 +105,7 @@ Returns the number of times the function has errored getIsExecuting(): boolean ``` -Defined in: [async-debouncer.ts:238](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L238) +Defined in: [async-debouncer.ts:242](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L242) Returns `true` if there is currently an execution in progress @@ -117,7 +121,7 @@ Returns `true` if there is currently an execution in progress getIsPending(): boolean ``` -Defined in: [async-debouncer.ts:231](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L231) +Defined in: [async-debouncer.ts:235](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L235) Returns `true` if there is a pending execution queued up for trailing execution @@ -133,7 +137,7 @@ Returns `true` if there is a pending execution queued up for trailing execution getLastResult(): undefined | ReturnType ``` -Defined in: [async-debouncer.ts:203](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L203) +Defined in: [async-debouncer.ts:207](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L207) Returns the last result of the debounced function @@ -149,7 +153,7 @@ Returns the last result of the debounced function getOptions(): Required> ``` -Defined in: [async-debouncer.ts:112](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L112) +Defined in: [async-debouncer.ts:116](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L116) Returns the current debouncer options @@ -165,7 +169,7 @@ Returns the current debouncer options getSettleCount(): number ``` -Defined in: [async-debouncer.ts:217](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L217) +Defined in: [async-debouncer.ts:221](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L221) Returns the number of times the function has settled (completed or errored) @@ -181,7 +185,7 @@ Returns the number of times the function has settled (completed or errored) getSuccessCount(): number ``` -Defined in: [async-debouncer.ts:210](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L210) +Defined in: [async-debouncer.ts:214](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L214) Returns the number of times the function has been executed successfully @@ -197,7 +201,7 @@ Returns the number of times the function has been executed successfully maybeExecute(...args): Promise> ``` -Defined in: [async-debouncer.ts:120](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L120) +Defined in: [async-debouncer.ts:124](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L124) Attempts to execute the debounced function If a call is already in progress, it will be queued @@ -220,7 +224,7 @@ If a call is already in progress, it will be queued setOptions(newOptions): void ``` -Defined in: [async-debouncer.ts:100](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L100) +Defined in: [async-debouncer.ts:104](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L104) Updates the debouncer options Returns the new options state diff --git a/docs/de/reference/classes/asyncratelimiter.md b/docs/de/reference/classes/asyncratelimiter.md index 49891be3a..4653b64d0 100644 --- a/docs/de/reference/classes/asyncratelimiter.md +++ b/docs/de/reference/classes/asyncratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:12:04.496Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:53:43.229Z' id: AsyncRateLimiter title: AsyncRateLimiter --- @@ -9,7 +9,7 @@ title: AsyncRateLimiter # Class: AsyncRateLimiter\ -Defined in: [async-rate-limiter.ts:76](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L76) +Defined in: [async-rate-limiter.ts:95](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L95) A class that creates an async rate-limited function. @@ -17,6 +17,16 @@ Rate limiting is a simple approach that allows a function to execute up to a lim then blocks all subsequent calls until the window passes. This can lead to "bursty" behavior where all executions happen immediately, followed by a complete block. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + +Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + For smoother execution patterns, consider using: - Throttling: Ensures consistent spacing between executions (e.g. max once per 200ms) - Debouncing: Waits for a pause in calls before executing (e.g. after 500ms of no calls) @@ -29,11 +39,12 @@ smoothing out frequent events, throttling or debouncing usually provide better u ```ts const rateLimiter = new AsyncRateLimiter( async (id: string) => await api.getData(id), - { limit: 5, window: 1000 } // 5 calls per second + { limit: 5, window: 1000, windowType: 'sliding' } // 5 calls per second with sliding window ); // Will execute immediately until limit reached, then block -await rateLimiter.maybeExecute('123'); +// Returns the API response directly +const data = await rateLimiter.maybeExecute('123'); ``` ## Type Parameters @@ -48,7 +59,7 @@ await rateLimiter.maybeExecute('123'); new AsyncRateLimiter(fn, initialOptions): AsyncRateLimiter ``` -Defined in: [async-rate-limiter.ts:85](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L85) +Defined in: [async-rate-limiter.ts:105](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L105) #### Parameters @@ -72,7 +83,7 @@ Defined in: [async-rate-limiter.ts:85](https://github.com/TanStack/pacer/blob/ma getErrorCount(): number ``` -Defined in: [async-rate-limiter.ts:209](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L209) +Defined in: [async-rate-limiter.ts:250](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L250) Returns the number of times the function has errored @@ -82,15 +93,33 @@ Returns the number of times the function has errored *** +### getIsExecuting() + +```ts +getIsExecuting(): boolean +``` + +Defined in: [async-rate-limiter.ts:264](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L264) + +Returns whether the function is currently executing + +#### Returns + +`boolean` + +*** + ### getMsUntilNextWindow() ```ts getMsUntilNextWindow(): number ``` -Defined in: [async-rate-limiter.ts:188](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L188) +Defined in: [async-rate-limiter.ts:225](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L225) Returns the number of milliseconds until the next execution will be possible +For fixed windows, this is the time until the current window resets +For sliding windows, this is the time until the oldest execution expires #### Returns @@ -104,7 +133,7 @@ Returns the number of milliseconds until the next execution will be possible getOptions(): Required> ``` -Defined in: [async-rate-limiter.ts:106](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L106) +Defined in: [async-rate-limiter.ts:126](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L126) Returns the current rate limiter options @@ -120,7 +149,7 @@ Returns the current rate limiter options getRejectionCount(): number ``` -Defined in: [async-rate-limiter.ts:216](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L216) +Defined in: [async-rate-limiter.ts:257](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L257) Returns the number of times the function has been rejected @@ -136,7 +165,7 @@ Returns the number of times the function has been rejected getRemainingInWindow(): number ``` -Defined in: [async-rate-limiter.ts:180](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L180) +Defined in: [async-rate-limiter.ts:215](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L215) Returns the number of remaining executions allowed in the current window @@ -152,7 +181,7 @@ Returns the number of remaining executions allowed in the current window getSettleCount(): number ``` -Defined in: [async-rate-limiter.ts:202](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L202) +Defined in: [async-rate-limiter.ts:243](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L243) Returns the number of times the function has been settled @@ -168,7 +197,7 @@ Returns the number of times the function has been settled getSuccessCount(): number ``` -Defined in: [async-rate-limiter.ts:195](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L195) +Defined in: [async-rate-limiter.ts:236](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L236) Returns the number of times the function has been executed @@ -184,7 +213,7 @@ Returns the number of times the function has been executed maybeExecute(...args): Promise> ``` -Defined in: [async-rate-limiter.ts:126](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L126) +Defined in: [async-rate-limiter.ts:146](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L146) Attempts to execute the rate-limited function if within the configured limits. Will reject execution if the number of calls in the current window exceeds the limit. @@ -220,7 +249,7 @@ await rateLimiter.maybeExecute('arg1', 'arg2'); // Rejected reset(): void ``` -Defined in: [async-rate-limiter.ts:223](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L223) +Defined in: [async-rate-limiter.ts:271](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L271) Resets the rate limiter state @@ -236,7 +265,7 @@ Resets the rate limiter state setOptions(newOptions): void ``` -Defined in: [async-rate-limiter.ts:99](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L99) +Defined in: [async-rate-limiter.ts:119](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L119) Updates the rate limiter options Returns the new options state diff --git a/docs/de/reference/classes/asyncthrottler.md b/docs/de/reference/classes/asyncthrottler.md index 444bff815..581c421d4 100644 --- a/docs/de/reference/classes/asyncthrottler.md +++ b/docs/de/reference/classes/asyncthrottler.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:12:04.492Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:53:43.226Z' id: AsyncThrottler title: AsyncThrottler --- @@ -9,7 +9,7 @@ title: AsyncThrottler # Class: AsyncThrottler\ -Defined in: [async-throttler.ts:76](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L76) +Defined in: [async-throttler.ts:80](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L80) A class that creates an async throttled function. @@ -17,6 +17,10 @@ Throttling limits how often a function can be executed, allowing only one execut Unlike debouncing which resets the delay timer on each call, throttling ensures the function executes at a regular interval regardless of how often it's called. +Unlike the non-async Throttler, this async version supports returning values from the throttled function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the throttled function. + This is useful for rate-limiting API calls, handling scroll/resize events, or any scenario where you want to ensure a maximum execution frequency. @@ -24,13 +28,13 @@ ensure a maximum execution frequency. ```ts const throttler = new AsyncThrottler(async (value: string) => { - await saveToAPI(value); + const result = await saveToAPI(value); + return result; // Return value is preserved }, { wait: 1000 }); // Will only execute once per second no matter how often called -inputElement.addEventListener('input', () => { - throttler.maybeExecute(inputElement.value); -}); +// Returns the API response directly +const result = await throttler.maybeExecute(inputElement.value); ``` ## Type Parameters @@ -45,7 +49,7 @@ inputElement.addEventListener('input', () => { new AsyncThrottler(fn, initialOptions): AsyncThrottler ``` -Defined in: [async-throttler.ts:89](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L89) +Defined in: [async-throttler.ts:93](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L93) #### Parameters @@ -69,7 +73,7 @@ Defined in: [async-throttler.ts:89](https://github.com/TanStack/pacer/blob/main/ cancel(): void ``` -Defined in: [async-throttler.ts:187](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L187) +Defined in: [async-throttler.ts:191](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L191) Cancels any pending execution or aborts any execution in progress @@ -85,7 +89,7 @@ Cancels any pending execution or aborts any execution in progress getErrorCount(): number ``` -Defined in: [async-throttler.ts:237](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L237) +Defined in: [async-throttler.ts:241](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L241) Returns the number of times the function has errored @@ -101,7 +105,7 @@ Returns the number of times the function has errored getIsExecuting(): boolean ``` -Defined in: [async-throttler.ts:251](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L251) +Defined in: [async-throttler.ts:255](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L255) Returns the current executing state @@ -117,7 +121,7 @@ Returns the current executing state getIsPending(): boolean ``` -Defined in: [async-throttler.ts:244](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L244) +Defined in: [async-throttler.ts:248](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L248) Returns the current pending state @@ -133,7 +137,7 @@ Returns the current pending state getLastExecutionTime(): number ``` -Defined in: [async-throttler.ts:202](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L202) +Defined in: [async-throttler.ts:206](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L206) Returns the last execution time @@ -149,7 +153,7 @@ Returns the last execution time getLastResult(): undefined | ReturnType ``` -Defined in: [async-throttler.ts:216](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L216) +Defined in: [async-throttler.ts:220](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L220) Returns the last result of the debounced function @@ -165,7 +169,7 @@ Returns the last result of the debounced function getNextExecutionTime(): number ``` -Defined in: [async-throttler.ts:209](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L209) +Defined in: [async-throttler.ts:213](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L213) Returns the next execution time @@ -181,7 +185,7 @@ Returns the next execution time getOptions(): Required> ``` -Defined in: [async-throttler.ts:115](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L115) +Defined in: [async-throttler.ts:119](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L119) Returns the current options @@ -197,7 +201,7 @@ Returns the current options getSettleCount(): number ``` -Defined in: [async-throttler.ts:230](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L230) +Defined in: [async-throttler.ts:234](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L234) Returns the number of times the function has settled (completed or errored) @@ -213,7 +217,7 @@ Returns the number of times the function has settled (completed or errored) getSuccessCount(): number ``` -Defined in: [async-throttler.ts:223](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L223) +Defined in: [async-throttler.ts:227](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L227) Returns the number of times the function has been executed successfully @@ -229,7 +233,7 @@ Returns the number of times the function has been executed successfully maybeExecute(...args): Promise> ``` -Defined in: [async-throttler.ts:123](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L123) +Defined in: [async-throttler.ts:127](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L127) Attempts to execute the throttled function If a call is already in progress, it may be blocked or queued depending on the `wait` option @@ -252,7 +256,7 @@ If a call is already in progress, it may be blocked or queued depending on the ` setOptions(newOptions): void ``` -Defined in: [async-throttler.ts:103](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L103) +Defined in: [async-throttler.ts:107](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L107) Updates the throttler options Returns the new options state diff --git a/docs/de/reference/classes/ratelimiter.md b/docs/de/reference/classes/ratelimiter.md index 4c25d5f23..b233dfa6e 100644 --- a/docs/de/reference/classes/ratelimiter.md +++ b/docs/de/reference/classes/ratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:12:04.480Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:53:43.216Z' id: RateLimiter title: RateLimiter --- @@ -9,7 +9,7 @@ title: RateLimiter # Class: RateLimiter\ -Defined in: [rate-limiter.ts:63](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L63) +Defined in: [rate-limiter.ts:77](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L77) A class that creates a rate-limited function. @@ -17,6 +17,12 @@ Rate limiting is a simple approach that allows a function to execute up to a lim then blocks all subsequent calls until the window passes. This can lead to "bursty" behavior where all executions happen immediately, followed by a complete block. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns, consider using: - Throttling: Ensures consistent spacing between executions (e.g. max once per 200ms) - Debouncing: Waits for a pause in calls before executing (e.g. after 500ms of no calls) @@ -29,7 +35,7 @@ smoothing out frequent events, throttling or debouncing usually provide better u ```ts const rateLimiter = new RateLimiter( (id: string) => api.getData(id), - { limit: 5, window: 1000 } // 5 calls per second + { limit: 5, window: 1000, windowType: 'sliding' } // 5 calls per second with sliding window ); // Will execute immediately until limit reached, then block @@ -48,7 +54,7 @@ rateLimiter.maybeExecute('123'); new RateLimiter(fn, initialOptions): RateLimiter ``` -Defined in: [rate-limiter.ts:69](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L69) +Defined in: [rate-limiter.ts:83](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L83) #### Parameters @@ -72,7 +78,7 @@ Defined in: [rate-limiter.ts:69](https://github.com/TanStack/pacer/blob/main/pac getExecutionCount(): number ``` -Defined in: [rate-limiter.ts:149](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L149) +Defined in: [rate-limiter.ts:175](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L175) Returns the number of times the function has been executed @@ -88,7 +94,7 @@ Returns the number of times the function has been executed getMsUntilNextWindow(): number ``` -Defined in: [rate-limiter.ts:171](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L171) +Defined in: [rate-limiter.ts:197](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L197) Returns the number of milliseconds until the next execution will be possible @@ -104,7 +110,7 @@ Returns the number of milliseconds until the next execution will be possible getOptions(): Required> ``` -Defined in: [rate-limiter.ts:90](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L90) +Defined in: [rate-limiter.ts:104](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L104) Returns the current rate limiter options @@ -120,7 +126,7 @@ Returns the current rate limiter options getRejectionCount(): number ``` -Defined in: [rate-limiter.ts:156](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L156) +Defined in: [rate-limiter.ts:182](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L182) Returns the number of times the function has been rejected @@ -136,7 +142,7 @@ Returns the number of times the function has been rejected getRemainingInWindow(): number ``` -Defined in: [rate-limiter.ts:163](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L163) +Defined in: [rate-limiter.ts:189](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L189) Returns the number of remaining executions allowed in the current window @@ -152,7 +158,7 @@ Returns the number of remaining executions allowed in the current window maybeExecute(...args): boolean ``` -Defined in: [rate-limiter.ts:109](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L109) +Defined in: [rate-limiter.ts:123](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L123) Attempts to execute the rate-limited function if within the configured limits. Will reject execution if the number of calls in the current window exceeds the limit. @@ -187,7 +193,7 @@ rateLimiter.maybeExecute('arg1', 'arg2'); // false reset(): void ``` -Defined in: [rate-limiter.ts:179](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L179) +Defined in: [rate-limiter.ts:208](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L208) Resets the rate limiter state @@ -203,7 +209,7 @@ Resets the rate limiter state setOptions(newOptions): void ``` -Defined in: [rate-limiter.ts:83](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L83) +Defined in: [rate-limiter.ts:97](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L97) Updates the rate limiter options Returns the new options state diff --git a/docs/de/reference/functions/asyncdebounce.md b/docs/de/reference/functions/asyncdebounce.md index 2368dbe08..d6fc20db8 100644 --- a/docs/de/reference/functions/asyncdebounce.md +++ b/docs/de/reference/functions/asyncdebounce.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-04-24T02:14:56.000Z' -translation-updated-at: '2025-05-06T20:42:13.857Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:53:43.212Z' id: asyncDebounce title: asyncDebounce --- @@ -10,21 +10,23 @@ title: asyncDebounce # Function: asyncDebounce() ```ts -function asyncDebounce(fn, initialOptions): (...args) => Promise +function asyncDebounce(fn, initialOptions): (...args) => Promise> ``` -Defined in: [async-debouncer.ts:219](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L219) +Defined in: [async-debouncer.ts:268](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L268) Creates an async debounced function that delays execution until after a specified wait time. The debounced function will only execute once the wait period has elapsed without any new calls. If called again during the wait period, the timer resets and a new wait period begins. +Unlike the non-async Debouncer, this async version supports returning values from the debounced function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the debounced function. + ## Type Parameters • **TFn** *extends* [`AnyAsyncFunction`](../type-aliases/anyasyncfunction.md) -• **TArgs** *extends* `any`[] - ## Parameters ### fn @@ -33,7 +35,7 @@ If called again during the wait period, the timer resets and a new wait period b ### initialOptions -`Omit`\<[`AsyncDebouncerOptions`](../interfaces/asyncdebounceroptions.md)\<`TFn`, `TArgs`\>, `"enabled"`\> +`Omit`\<[`AsyncDebouncerOptions`](../interfaces/asyncdebounceroptions.md)\<`TFn`\>, `"enabled"`\> ## Returns @@ -46,21 +48,21 @@ If a call is already in progress, it will be queued #### args -...`TArgs` +...`Parameters`\<`TFn`\> ### Returns -`Promise`\<`void`\> +`Promise`\<`undefined` \| `ReturnType`\<`TFn`\>\> ## Example ```ts const debounced = asyncDebounce(async (value: string) => { - await saveToAPI(value); + const result = await saveToAPI(value); + return result; // Return value is preserved }, { wait: 1000 }); // Will only execute once, 1 second after the last call -await debounced("first"); // Cancelled -await debounced("second"); // Cancelled -await debounced("third"); // Executes after 1s +// Returns the API response directly +const result = await debounced("third"); ``` diff --git a/docs/de/reference/functions/asyncratelimit.md b/docs/de/reference/functions/asyncratelimit.md index 71d857d4c..78ffc3909 100644 --- a/docs/de/reference/functions/asyncratelimit.md +++ b/docs/de/reference/functions/asyncratelimit.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:12:04.471Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:53:43.208Z' id: asyncRateLimit title: asyncRateLimit --- @@ -13,10 +13,20 @@ title: asyncRateLimit function asyncRateLimit(fn, initialOptions): (...args) => Promise> ``` -Defined in: [async-rate-limiter.ts:262](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L262) +Defined in: [async-rate-limiter.ts:322](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L322) Creates an async rate-limited function that will execute the provided function up to a maximum number of times within a time window. +Unlike the non-async rate limiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + Note that rate limiting is a simpler form of execution control compared to throttling or debouncing: - A rate limiter will allow all executions until the limit is reached, then block all subsequent calls until the window resets - A throttler ensures even spacing between executions, which can be better for consistent performance @@ -72,10 +82,11 @@ await rateLimiter.maybeExecute('arg1', 'arg2'); // Rejected ## Example ```ts -// Rate limit to 5 calls per minute +// Rate limit to 5 calls per minute with a sliding window const rateLimited = asyncRateLimit(makeApiCall, { limit: 5, window: 60000, + windowType: 'sliding', onReject: (rateLimiter) => { console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } @@ -83,7 +94,8 @@ const rateLimited = asyncRateLimit(makeApiCall, { // First 5 calls will execute immediately // Additional calls will be rejected until the minute window resets -await rateLimited(); +// Returns the API response directly +const result = await rateLimited(); // For more even execution, consider using throttle instead: const throttled = throttle(makeApiCall, { wait: 12000 }); // One call every 12 seconds diff --git a/docs/de/reference/functions/asyncthrottle.md b/docs/de/reference/functions/asyncthrottle.md index edfe3e0ae..f711a9608 100644 --- a/docs/de/reference/functions/asyncthrottle.md +++ b/docs/de/reference/functions/asyncthrottle.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-04-24T02:14:56.000Z' -translation-updated-at: '2025-05-06T20:42:13.853Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:53:43.205Z' id: asyncThrottle title: asyncThrottle --- @@ -10,21 +10,23 @@ title: asyncThrottle # Function: asyncThrottle() ```ts -function asyncThrottle(fn, initialOptions): (...args) => Promise +function asyncThrottle(fn, initialOptions): (...args) => Promise> ``` -Defined in: [async-throttler.ts:223](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L223) +Defined in: [async-throttler.ts:281](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L281) Creates an async throttled function that limits how often the function can execute. The throttled function will execute at most once per wait period, even if called multiple times. If called while executing, it will wait until execution completes before scheduling the next call. +Unlike the non-async Throttler, this async version supports returning values from the throttled function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the throttled function. + ## Type Parameters • **TFn** *extends* [`AnyAsyncFunction`](../type-aliases/anyasyncfunction.md) -• **TArgs** *extends* `any`[] - ## Parameters ### fn @@ -33,7 +35,7 @@ If called while executing, it will wait until execution completes before schedul ### initialOptions -`Omit`\<[`AsyncThrottlerOptions`](../interfaces/asyncthrottleroptions.md)\<`TFn`, `TArgs`\>, `"enabled"`\> +`Omit`\<[`AsyncThrottlerOptions`](../interfaces/asyncthrottleroptions.md)\<`TFn`\>, `"enabled"`\> ## Returns @@ -46,20 +48,21 @@ If a call is already in progress, it may be blocked or queued depending on the ` #### args -...`TArgs` +...`Parameters`\<`TFn`\> ### Returns -`Promise`\<`void`\> +`Promise`\<`undefined` \| `ReturnType`\<`TFn`\>\> ## Example ```ts -const throttled = asyncThrottle(async () => { - await someAsyncOperation(); +const throttled = asyncThrottle(async (value: string) => { + const result = await saveToAPI(value); + return result; // Return value is preserved }, { wait: 1000 }); // This will execute at most once per second -await throttled(); -await throttled(); // Waits 1 second before executing +// Returns the API response directly +const result = await throttled(inputElement.value); ``` diff --git a/docs/de/reference/functions/ratelimit.md b/docs/de/reference/functions/ratelimit.md index fdf28e381..97e4c5714 100644 --- a/docs/de/reference/functions/ratelimit.md +++ b/docs/de/reference/functions/ratelimit.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:12:04.463Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:53:43.201Z' id: rateLimit title: rateLimit --- @@ -13,7 +13,7 @@ title: rateLimit function rateLimit(fn, initialOptions): (...args) => boolean ``` -Defined in: [rate-limiter.ts:216](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L216) +Defined in: [rate-limiter.ts:252](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L252) Creates a rate-limited function that will execute the provided function up to a maximum number of times within a time window. @@ -22,6 +22,12 @@ Note that rate limiting is a simpler form of execution control compared to throt - A throttler ensures even spacing between executions, which can be better for consistent performance - A debouncer collapses multiple calls into one, which is better for handling bursts of events +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + Consider using throttle() or debounce() if you need more intelligent execution control. Use rate limiting when you specifically need to enforce a hard limit on the number of executions within a time period. @@ -71,10 +77,11 @@ rateLimiter.maybeExecute('arg1', 'arg2'); // false ## Example ```ts -// Rate limit to 5 calls per minute +// Rate limit to 5 calls per minute with a sliding window const rateLimited = rateLimit(makeApiCall, { limit: 5, window: 60000, + windowType: 'sliding', onReject: (rateLimiter) => { console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/de/reference/interfaces/asyncratelimiteroptions.md b/docs/de/reference/interfaces/asyncratelimiteroptions.md index 26430fae7..4fde3cd5b 100644 --- a/docs/de/reference/interfaces/asyncratelimiteroptions.md +++ b/docs/de/reference/interfaces/asyncratelimiteroptions.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:12:04.443Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:53:43.197Z' id: AsyncRateLimiterOptions title: AsyncRateLimiterOptions --- @@ -149,3 +149,18 @@ window: number; Defined in: [async-rate-limiter.ts:38](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L38) Time window in milliseconds within which the limit applies + +*** + +### windowType? + +```ts +optional windowType: "fixed" | "sliding"; +``` + +Defined in: [async-rate-limiter.ts:45](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L45) + +Type of window to use for rate limiting +- 'fixed': Uses a fixed window that resets after the window period +- 'sliding': Uses a sliding window that allows executions as old ones expire +Defaults to 'fixed' diff --git a/docs/de/reference/interfaces/ratelimiteroptions.md b/docs/de/reference/interfaces/ratelimiteroptions.md index 5413b2f3c..c89c14dc1 100644 --- a/docs/de/reference/interfaces/ratelimiteroptions.md +++ b/docs/de/reference/interfaces/ratelimiteroptions.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:12:04.417Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:53:43.193Z' id: RateLimiterOptions title: RateLimiterOptions --- @@ -97,3 +97,18 @@ window: number; Defined in: [rate-limiter.ts:27](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L27) Time window in milliseconds within which the limit applies + +*** + +### windowType? + +```ts +optional windowType: "fixed" | "sliding"; +``` + +Defined in: [rate-limiter.ts:34](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L34) + +Type of window to use for rate limiting +- 'fixed': Uses a fixed window that resets after the window period +- 'sliding': Uses a sliding window that allows executions as old ones expire +Defaults to 'fixed' diff --git a/docs/fr/framework/react/reference/functions/useasyncratelimiter.md b/docs/fr/framework/react/reference/functions/useasyncratelimiter.md index 86cead396..c57086d6b 100644 --- a/docs/fr/framework/react/reference/functions/useasyncratelimiter.md +++ b/docs/fr/framework/react/reference/functions/useasyncratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:14:43.301Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:56:39.565Z' id: useAsyncRateLimiter title: useAsyncRateLimiter --- @@ -13,7 +13,7 @@ title: useAsyncRateLimiter function useAsyncRateLimiter(fn, options): AsyncRateLimiter ``` -Defined in: [react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts:43](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts#L43) +Defined in: [react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts:54](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts#L54) A low-level React hook that creates an `AsyncRateLimiter` instance to limit how many times an async function can execute within a time window. @@ -24,6 +24,16 @@ Rate limiting allows an async function to execute up to a specified limit within then blocks subsequent calls until the window passes. This is useful for respecting API rate limits, managing resource constraints, or controlling bursts of async operations. +Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + ## Type Parameters • **TFn** *extends* `AnyAsyncFunction` @@ -45,21 +55,22 @@ managing resource constraints, or controlling bursts of async operations. ## Example ```tsx -// Basic API call rate limiting +// Basic API call rate limiting with return value const { maybeExecute } = useAsyncRateLimiter( async (id: string) => { const data = await api.fetchData(id); - return data; + return data; // Return value is preserved }, { limit: 5, window: 1000 } // 5 calls per second ); -// With state management +// With state management and return value const [data, setData] = useState(null); const { maybeExecute } = useAsyncRateLimiter( async (query) => { const result = await searchAPI(query); setData(result); + return result; // Return value can be used by the caller }, { limit: 10, diff --git a/docs/fr/framework/react/reference/functions/useratelimitedcallback.md b/docs/fr/framework/react/reference/functions/useratelimitedcallback.md index b8615701c..1398e3430 100644 --- a/docs/fr/framework/react/reference/functions/useratelimitedcallback.md +++ b/docs/fr/framework/react/reference/functions/useratelimitedcallback.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-04-24T02:14:56.000Z' -translation-updated-at: '2025-05-06T20:43:04.141Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:56:39.562Z' id: useRateLimitedCallback title: useRateLimitedCallback --- @@ -13,7 +13,7 @@ title: useRateLimitedCallback function useRateLimitedCallback(fn, options): (...args) => boolean ``` -Defined in: [rate-limiter/useRateLimitedCallback.ts:52](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedCallback.ts#L52) +Defined in: [react-pacer/src/rate-limiter/useRateLimitedCallback.ts:59](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedCallback.ts#L59) A React hook that creates a rate-limited version of a callback function. This hook is essentially a wrapper around the basic `rateLimiter` function @@ -26,6 +26,12 @@ or debouncing, it does not attempt to space out or intelligently collapse calls. This can lead to bursts of rapid executions followed by periods where all calls are blocked. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns, consider: - useThrottledCallback: When you want consistent spacing between executions (e.g. UI updates) - useDebouncedCallback: When you want to collapse rapid calls into a single execution (e.g. search input) @@ -57,7 +63,7 @@ Consider using the `useRateLimiter` hook instead. ### options -`RateLimiterOptions`\<`TFn`, `TArgs`\> +`RateLimiterOptions`\<`TFn`\> ## Returns @@ -76,7 +82,7 @@ Consider using the `useRateLimiter` hook instead. ## Example ```tsx -// Rate limit API calls to maximum 5 calls per minute +// Rate limit API calls to maximum 5 calls per minute with a sliding window const makeApiCall = useRateLimitedCallback( (data: ApiData) => { return fetch('/api/endpoint', { method: 'POST', body: JSON.stringify(data) }); @@ -84,6 +90,7 @@ const makeApiCall = useRateLimitedCallback( { limit: 5, window: 60000, // 1 minute + windowType: 'sliding', onReject: () => { console.warn('API rate limit reached. Please wait before trying again.'); } diff --git a/docs/fr/framework/react/reference/functions/useratelimitedstate.md b/docs/fr/framework/react/reference/functions/useratelimitedstate.md index 859df0dc3..6a281c2fd 100644 --- a/docs/fr/framework/react/reference/functions/useratelimitedstate.md +++ b/docs/fr/framework/react/reference/functions/useratelimitedstate.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:14:43.265Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:56:39.558Z' id: useRateLimitedState title: useRateLimitedState --- @@ -13,7 +13,7 @@ title: useRateLimitedState function useRateLimitedState(value, options): [TValue, Dispatch>, RateLimiter>>] ``` -Defined in: [react-pacer/src/rate-limiter/useRateLimitedState.ts:59](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedState.ts#L59) +Defined in: [react-pacer/src/rate-limiter/useRateLimitedState.ts:66](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedState.ts#L66) A React hook that creates a rate-limited state value that enforces a hard limit on state updates within a time window. This hook combines React's useState with rate limiting functionality to provide controlled state updates. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - useThrottledState: When you want consistent spacing between updates (e.g. UI changes) - useDebouncedState: When you want to collapse rapid updates into a single update (e.g. search input) @@ -57,16 +63,18 @@ consider using the lower-level useRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update state at most 5 times per minute +// Basic rate limiting - update state at most 5 times per minute with a sliding window const [value, setValue, rateLimiter] = useRateLimitedState(0, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); -// With rejection callback +// With rejection callback and fixed window const [value, setValue] = useRateLimitedState(0, { limit: 3, window: 5000, + windowType: 'fixed', onReject: (rateLimiter) => { alert(`Rate limit reached. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/fr/framework/react/reference/functions/useratelimitedvalue.md b/docs/fr/framework/react/reference/functions/useratelimitedvalue.md index 6d373661c..88bec97aa 100644 --- a/docs/fr/framework/react/reference/functions/useratelimitedvalue.md +++ b/docs/fr/framework/react/reference/functions/useratelimitedvalue.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:14:43.260Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:56:39.554Z' id: useRateLimitedValue title: useRateLimitedValue --- @@ -13,7 +13,7 @@ title: useRateLimitedValue function useRateLimitedValue(value, options): [TValue, RateLimiter>>] ``` -Defined in: [react-pacer/src/rate-limiter/useRateLimitedValue.ts:47](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedValue.ts#L47) +Defined in: [react-pacer/src/rate-limiter/useRateLimitedValue.ts:55](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedValue.ts#L55) A high-level React hook that creates a rate-limited version of a value that updates at most a certain number of times within a time window. This hook uses React's useState internally to manage the rate-limited state. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - useThrottledValue: When you want consistent spacing between updates (e.g. UI changes) - useDebouncedValue: When you want to collapse rapid updates into a single update (e.g. search input) @@ -56,16 +62,18 @@ consider using the lower-level useRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update at most 5 times per minute +// Basic rate limiting - update at most 5 times per minute with a sliding window const [rateLimitedValue, rateLimiter] = useRateLimitedValue(rawValue, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); -// With rejection callback +// With rejection callback and fixed window const [rateLimitedValue, rateLimiter] = useRateLimitedValue(rawValue, { limit: 3, window: 5000, + windowType: 'fixed', onReject: (rateLimiter) => { console.log(`Update rejected. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/fr/framework/react/reference/functions/useratelimiter.md b/docs/fr/framework/react/reference/functions/useratelimiter.md index 8ef0eb1c6..2a933aa3d 100644 --- a/docs/fr/framework/react/reference/functions/useratelimiter.md +++ b/docs/fr/framework/react/reference/functions/useratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:14:43.256Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:56:39.550Z' id: useRateLimiter title: useRateLimiter --- @@ -13,7 +13,7 @@ title: useRateLimiter function useRateLimiter(fn, options): RateLimiter ``` -Defined in: [react-pacer/src/rate-limiter/useRateLimiter.ts:48](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimiter.ts#L48) +Defined in: [react-pacer/src/rate-limiter/useRateLimiter.ts:55](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimiter.ts#L55) A low-level React hook that creates a `RateLimiter` instance to enforce rate limits on function execution. @@ -24,6 +24,12 @@ Rate limiting is a simple "hard limit" approach that allows executions until a m a time window, then blocks all subsequent calls until the window resets. Unlike throttling or debouncing, it does not attempt to space out or collapse executions intelligently. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns: - Use throttling when you want consistent spacing between executions (e.g. UI updates) - Use debouncing when you want to collapse rapid-fire events (e.g. search input) @@ -57,10 +63,11 @@ The hook returns an object containing: ## Example ```tsx -// Basic rate limiting - max 5 calls per minute +// Basic rate limiting - max 5 calls per minute with a sliding window const { maybeExecute } = useRateLimiter(apiCall, { limit: 5, window: 60000, + windowType: 'sliding', }); // Monitor rate limit status diff --git a/docs/fr/framework/solid/reference/functions/createasyncratelimiter.md b/docs/fr/framework/solid/reference/functions/createasyncratelimiter.md index 49b58fea4..32248da42 100644 --- a/docs/fr/framework/solid/reference/functions/createasyncratelimiter.md +++ b/docs/fr/framework/solid/reference/functions/createasyncratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:14:43.226Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:56:39.543Z' id: createAsyncRateLimiter title: createAsyncRateLimiter --- @@ -13,7 +13,7 @@ title: createAsyncRateLimiter function createAsyncRateLimiter(fn, initialOptions): SolidAsyncRateLimiter ``` -Defined in: [async-rate-limiter/createAsyncRateLimiter.ts:62](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L62) +Defined in: [async-rate-limiter/createAsyncRateLimiter.ts:73](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L73) A low-level Solid hook that creates an `AsyncRateLimiter` instance to limit how many times an async function can execute within a time window. @@ -24,6 +24,16 @@ Rate limiting allows an async function to execute up to a specified limit within then blocks subsequent calls until the window passes. This is useful for respecting API rate limits, managing resource constraints, or controlling bursts of async operations. +Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + ## Type Parameters • **TFn** *extends* `AnyAsyncFunction` @@ -45,21 +55,22 @@ managing resource constraints, or controlling bursts of async operations. ## Example ```tsx -// Basic API call rate limiting +// Basic API call rate limiting with return value const { maybeExecute } = createAsyncRateLimiter( async (id: string) => { const data = await api.fetchData(id); - return data; + return data; // Return value is preserved }, { limit: 5, window: 1000 } // 5 calls per second ); -// With state management +// With state management and return value const [data, setData] = createSignal(null); const { maybeExecute } = createAsyncRateLimiter( async (query) => { const result = await searchAPI(query); setData(result); + return result; // Return value can be used by the caller }, { limit: 10, diff --git a/docs/fr/framework/solid/reference/functions/createratelimitedsignal.md b/docs/fr/framework/solid/reference/functions/createratelimitedsignal.md index 2cc9913bd..d2fff9163 100644 --- a/docs/fr/framework/solid/reference/functions/createratelimitedsignal.md +++ b/docs/fr/framework/solid/reference/functions/createratelimitedsignal.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:14:43.201Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:56:39.540Z' id: createRateLimitedSignal title: createRateLimitedSignal --- @@ -13,7 +13,7 @@ title: createRateLimitedSignal function createRateLimitedSignal(value, initialOptions): [Accessor, Setter, SolidRateLimiter>] ``` -Defined in: [rate-limiter/createRateLimitedSignal.ts:57](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedSignal.ts#L57) +Defined in: [rate-limiter/createRateLimitedSignal.ts:65](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedSignal.ts#L65) A Solid hook that creates a rate-limited state value that enforces a hard limit on state updates within a time window. This hook combines Solid's createSignal with rate limiting functionality to provide controlled state updates. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - createThrottledSignal: When you want consistent spacing between updates (e.g. UI changes) - createDebouncedSignal: When you want to collapse rapid updates into a single update (e.g. search input) @@ -57,16 +63,18 @@ consider using the lower-level createRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update state at most 5 times per minute +// Basic rate limiting - update state at most 5 times per minute with a sliding window const [value, setValue, rateLimiter] = createRateLimitedSignal(0, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); -// With rejection callback +// With rejection callback and fixed window const [value, setValue] = createRateLimitedSignal(0, { limit: 3, window: 5000, + windowType: 'fixed', onReject: (rateLimiter) => { alert(`Rate limit reached. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/fr/framework/solid/reference/functions/createratelimitedvalue.md b/docs/fr/framework/solid/reference/functions/createratelimitedvalue.md index a9a32ee20..10bb9c8b9 100644 --- a/docs/fr/framework/solid/reference/functions/createratelimitedvalue.md +++ b/docs/fr/framework/solid/reference/functions/createratelimitedvalue.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:14:43.196Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:56:39.536Z' id: createRateLimitedValue title: createRateLimitedValue --- @@ -13,7 +13,7 @@ title: createRateLimitedValue function createRateLimitedValue(value, initialOptions): [Accessor, SolidRateLimiter>] ``` -Defined in: [rate-limiter/createRateLimitedValue.ts:43](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedValue.ts#L43) +Defined in: [rate-limiter/createRateLimitedValue.ts:50](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedValue.ts#L50) A high-level Solid hook that creates a rate-limited version of a value that updates at most a certain number of times within a time window. This hook uses Solid's createSignal internally to manage the rate-limited state. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - createThrottledValue: When you want consistent spacing between updates (e.g. UI changes) - createDebouncedValue: When you want to collapse rapid updates into a single update (e.g. search input) @@ -56,10 +62,11 @@ consider using the lower-level createRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update at most 5 times per minute +// Basic rate limiting - update at most 5 times per minute with a sliding window const [rateLimitedValue, rateLimiter] = createRateLimitedValue(rawValue, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); // Use the rate-limited value diff --git a/docs/fr/framework/solid/reference/functions/createratelimiter.md b/docs/fr/framework/solid/reference/functions/createratelimiter.md index b2404c4ef..bf82bc8d5 100644 --- a/docs/fr/framework/solid/reference/functions/createratelimiter.md +++ b/docs/fr/framework/solid/reference/functions/createratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:14:43.193Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:56:39.532Z' id: createRateLimiter title: createRateLimiter --- @@ -13,7 +13,7 @@ title: createRateLimiter function createRateLimiter(fn, initialOptions): SolidRateLimiter ``` -Defined in: [rate-limiter/createRateLimiter.ts:61](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts#L61) +Defined in: [rate-limiter/createRateLimiter.ts:68](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts#L68) A low-level Solid hook that creates a `RateLimiter` instance to enforce rate limits on function execution. @@ -24,6 +24,12 @@ Rate limiting is a simple "hard limit" approach that allows executions until a m a time window, then blocks all subsequent calls until the window resets. Unlike throttling or debouncing, it does not attempt to space out or collapse executions intelligently. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns: - Use throttling when you want consistent spacing between executions (e.g. UI updates) - Use debouncing when you want to collapse rapid-fire events (e.g. search input) @@ -50,10 +56,11 @@ For smoother execution patterns: ## Example ```tsx -// Basic rate limiting - max 5 calls per minute +// Basic rate limiting - max 5 calls per minute with a sliding window const rateLimiter = createRateLimiter(apiCall, { limit: 5, window: 60000, + windowType: 'sliding' }); // Monitor rate limit status diff --git a/docs/fr/guides/debouncing.md b/docs/fr/guides/debouncing.md index 80631018a..20c47b067 100644 --- a/docs/fr/guides/debouncing.md +++ b/docs/fr/guides/debouncing.md @@ -1,62 +1,62 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:17:20.628Z' -title: Guide sur le debouncing +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:59:20.352Z' +title: Guide sur le débouncement id: debouncing --- -# Guide sur le Débounçage (Debouncing) +# Guide sur le Débounce (Debouncing) -La limitation de débit (Rate Limiting), le throttling et le débounçage (Debouncing) sont trois approches distinctes pour contrôler la fréquence d'exécution des fonctions. Chaque technique bloque les exécutions différemment, les rendant "lossy" (avec perte) - ce qui signifie que certains appels de fonction ne s'exécuteront pas lorsqu'ils sont demandés trop fréquemment. Comprendre quand utiliser chaque approche est crucial pour créer des applications performantes et fiables. Ce guide couvrira les concepts de débounçage de TanStack Pacer. +Le *Rate Limiting* (Limitation de débit), le *Throttling* (Limitation de fréquence) et le *Débounce* (Antirebond) sont trois approches distinctes pour contrôler la fréquence d'exécution des fonctions. Chaque technique bloque les exécutions différemment, les rendant "lossy" (avec perte) - ce qui signifie que certains appels de fonction ne seront pas exécutés lorsqu'ils sont demandés trop fréquemment. Comprendre quand utiliser chaque approche est crucial pour créer des applications performantes et fiables. Ce guide couvrira les concepts de *Débounce* de TanStack Pacer. -## Concept de Débounçage (Debouncing) +## Concept de Débounce -Le débounçage est une technique qui retarde l'exécution d'une fonction jusqu'à ce qu'une période d'inactivité spécifiée se soit écoulée. Contrairement à la limitation de débit qui autorise des rafales d'exécutions jusqu'à une limite, ou au throttling qui garantit des exécutions régulièrement espacées, le débounçage regroupe plusieurs appels rapides de fonction en une seule exécution qui ne se produit qu'après l'arrêt des appels. Cela rend le débounçage idéal pour gérer des rafales d'événements où seul l'état final après l'arrêt de l'activité vous intéresse. +Le *Débounce* est une technique qui retarde l'exécution d'une fonction jusqu'à ce qu'une période d'inactivité spécifiée se soit écoulée. Contrairement à la limitation de débit qui autorise des rafales d'exécutions jusqu'à une limite, ou à la limitation de fréquence qui garantit des exécutions régulièrement espacées, le *débounce* regroupe plusieurs appels rapides de fonction en une seule exécution qui se produit uniquement après l'arrêt des appels. Cela rend le *débounce* idéal pour gérer des rafales d'événements où seul l'état final après l'arrêt de l'activité compte. -### Visualisation du Débounçage +### Visualisation du Débounce ```text -Debouncing (wait: 3 ticks) -Timeline: [1 second per tick] -Calls: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ -Executed: ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ⏳ -> ✅ ❌ ⏳ -> ✅ +Débounce (attente : 3 ticks) +Chronologie : [1 seconde par tick] +Appels : ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ +Exécutés : ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ⏳ -> ✅ ❌ ⏳ -> ✅ [=================================================================] ^ Exécution ici après - 3 ticks sans appel + 3 ticks sans appels [Rafale d'appels] [Plus d'appels] [Attente] [Nouvelle rafale] Aucune exécution Réinitialise le timer [Exécution différée] [Attente] [Exécution différée] ``` -### Quand Utiliser le Débounçage +### Quand utiliser le Débounce -Le débounçage est particulièrement efficace lorsque vous souhaitez attendre une "pause" dans l'activité avant d'agir. Cela le rend idéal pour gérer les saisies utilisateur ou d'autres événements se déclenchant rapidement où seul l'état final vous intéresse. +Le *débounce* est particulièrement efficace lorsque vous souhaitez attendre une "pause" dans l'activité avant d'agir. Cela le rend idéal pour gérer les saisies utilisateur ou d'autres événements à déclenchement rapide où seul l'état final compte. Cas d'utilisation courants : -- Champs de recherche où vous voulez attendre que l'utilisateur finisse de taper -- Validation de formulaire qui ne devrait pas s'exécuter à chaque frappe +- Champs de recherche où vous souhaitez attendre que l'utilisateur finisse de taper +- Validation de formulaire qui ne doit pas s'exécuter à chaque frappe - Calculs de redimensionnement de fenêtre coûteux en performance -- Sauvegarde automatique de brouillons pendant l'édition de contenu -- Appels API qui ne devraient se produire qu'après l'arrêt de l'activité utilisateur -- Tout scénario où seul la valeur finale après des changements rapides vous intéresse +- Sauvegarde automatique de brouillons lors de l'édition de contenu +- Appels API qui ne doivent se produire qu'après l'arrêt de l'activité utilisateur +- Tout scénario où seul la valeur finale après des changements rapides compte -### Quand Ne Pas Utiliser le Débounçage +### Quand ne pas utiliser le Débounce -Le débounçage pourrait ne pas être le meilleur choix lorsque : -- Vous avez besoin d'une exécution garantie sur une période spécifique (utilisez plutôt le [throttling](../guides/throttling)) -- Vous ne pouvez pas vous permettre de manquer des exécutions (utilisez plutôt la [mise en file d'attente (queueing)](../guides/queueing)) +Le *débounce* n'est peut-être pas le meilleur choix lorsque : +- Vous avez besoin d'une exécution garantie sur une période spécifique (utilisez plutôt le [*throttling*](../guides/throttling)) +- Vous ne pouvez pas vous permettre de manquer des exécutions (utilisez plutôt la [mise en file d'attente](../guides/queueing)) -## Débounçage dans TanStack Pacer +## Débounce dans TanStack Pacer -TanStack Pacer fournit à la fois du débounçage synchrone et asynchrone via les classes `Debouncer` et `AsyncDebouncer` respectivement (et leurs fonctions correspondantes `debounce` et `asyncDebounce`). +TanStack Pacer fournit des fonctionnalités de *débounce* synchrones et asynchrones via les classes `Debouncer` et `AsyncDebouncer` respectivement (et leurs fonctions correspondantes `debounce` et `asyncDebounce`). -### Utilisation Basique avec `debounce` +### Utilisation basique avec `debounce` -La fonction `debounce` est la manière la plus simple d'ajouter du débounçage à n'importe quelle fonction : +La fonction `debounce` est le moyen le plus simple d'ajouter un *débounce* à n'importe quelle fonction : ```ts import { debounce } from '@tanstack/pacer' -// Débounçage d'une saisie de recherche pour attendre que l'utilisateur arrête de taper +// Appliquer un débounce à la recherche pour attendre que l'utilisateur arrête de taper const debouncedSearch = debounce( (searchTerm: string) => performSearch(searchTerm), { @@ -69,9 +69,9 @@ searchInput.addEventListener('input', (e) => { }) ``` -### Utilisation Avancée avec la Classe `Debouncer` +### Utilisation avancée avec la classe `Debouncer` -Pour plus de contrôle sur le comportement de débounçage, vous pouvez utiliser directement la classe `Debouncer` : +Pour plus de contrôle sur le comportement du *débounce*, vous pouvez utiliser directement la classe `Debouncer` : ```ts import { Debouncer } from '@tanstack/pacer' @@ -94,7 +94,7 @@ searchDebouncer.cancel() ### Exécutions Leading et Trailing -Le débounçage synchrone prend en charge les exécutions sur les fronts montants (leading) et descendants (trailing) : +Le *debouncer* synchrone prend en charge les exécutions sur les fronts montants (leading) et descendants (trailing) : ```ts const debouncedFn = debounce(fn, { @@ -110,30 +110,30 @@ const debouncedFn = debounce(fn, { - `trailing: false` - Aucune exécution après la période d'attente Modèles courants : -- `{ leading: false, trailing: true }` - Par défaut, exécute après l'attente -- `{ leading: true, trailing: false }` - Exécute immédiatement, ignore les appels suivants -- `{ leading: true, trailing: true }` - Exécute à la fois au premier appel et après l'attente +- `{ leading: false, trailing: true }` - Par défaut, exécution après attente +- `{ leading: true, trailing: false }` - Exécution immédiate, ignore les appels suivants +- `{ leading: true, trailing: true }` - Exécution au premier appel et après attente -### Temps d'Attente Maximum (Max Wait Time) +### Temps d'attente maximum -Le Debouncer de TanStack Pacer n'a intentionnellement PAS d'option `maxWait` comme d'autres bibliothèques de débounçage. Si vous avez besoin de laisser les exécutions s'étaler sur une période plus longue, envisagez plutôt d'utiliser la technique de [throttling](../guides/throttling). +Le *Debouncer* de TanStack Pacer ne propose intentionnellement PAS d'option `maxWait` comme d'autres bibliothèques de *débounce*. Si vous avez besoin d'exécutions réparties sur une période plus longue, envisagez plutôt d'utiliser la technique de [*throttling*](../guides/throttling). ### Activation/Désactivation -La classe `Debouncer` prend en charge l'activation/désactivation via l'option `enabled`. En utilisant la méthode `setOptions`, vous pouvez activer/désactiver le débounçage à tout moment : +La classe `Debouncer` prend en charge l'activation/désactivation via l'option `enabled`. En utilisant la méthode `setOptions`, vous pouvez activer/désactiver le *debouncer* à tout moment : ```ts const debouncer = new Debouncer(fn, { wait: 500, enabled: false }) // Désactivé par défaut debouncer.setOptions({ enabled: true }) // Activer à tout moment ``` -Si vous utilisez un adaptateur de framework où les options de débounçage sont réactives, vous pouvez définir l'option `enabled` sur une valeur conditionnelle pour activer/désactiver le débounçage à la volée : +Si vous utilisez un adaptateur de framework où les options du *debouncer* sont réactives, vous pouvez définir l'option `enabled` sur une valeur conditionnelle pour activer/désactiver le *debouncer* à la volée : ```ts // Exemple React const debouncer = useDebouncer( setSearch, - { wait: 500, enabled: searchInput.value.length > 3 } // Activer/désactiver selon la longueur de la saisie SI vous utilisez un adaptateur de framework prenant en charge les options réactives + { wait: 500, enabled: searchInput.value.length > 3 } // Activer/désactiver selon la longueur de l'entrée SI vous utilisez un adaptateur de framework prenant en charge les options réactives ) ``` @@ -143,15 +143,15 @@ Cependant, si vous utilisez la fonction `debounce` ou la classe `Debouncer` dire // Exemple Solid const debouncer = new Debouncer(fn, { wait: 500, enabled: false }) // Désactivé par défaut createEffect(() => { - debouncer.setOptions({ enabled: search().length > 3 }) // Activer/désactiver selon la longueur de la saisie + debouncer.setOptions({ enabled: search().length > 3 }) // Activer/désactiver selon la longueur de l'entrée }) ``` -### Options de Callback +### Options de callback -Les débounçeurs synchrones et asynchrones prennent en charge des options de callback pour gérer différents aspects du cycle de vie du débounçage : +Les *debouncers* synchrones et asynchrones prennent en charge des options de callback pour gérer différents aspects du cycle de vie du *débounce* : -#### Callbacks du Débounçage Synchrone +#### Callbacks du Debouncer synchrone Le `Debouncer` synchrone prend en charge le callback suivant : @@ -165,9 +165,9 @@ const debouncer = new Debouncer(fn, { }) ``` -Le callback `onExecute` est appelé après chaque exécution réussie de la fonction débouncée, ce qui le rend utile pour suivre les exécutions, mettre à jour l'état de l'UI ou effectuer des opérations de nettoyage. +Le callback `onExecute` est appelé après chaque exécution réussie de la fonction avec *débounce*, ce qui le rend utile pour suivre les exécutions, mettre à jour l'état de l'interface ou effectuer des opérations de nettoyage. -#### Callbacks du Débounçage Asynchrone +#### Callbacks du Debouncer asynchrone Le `AsyncDebouncer` asynchrone a un ensemble de callbacks différent par rapport à la version synchrone. @@ -178,50 +178,44 @@ const asyncDebouncer = new AsyncDebouncer(async (value) => { wait: 500, onSuccess: (result, debouncer) => { // Appelé après chaque exécution réussie - console.log('Fonction async exécutée', debouncer.getSuccessCount()) + console.log('Fonction asynchrone exécutée', debouncer.getSuccessCount()) }, onSettled: (debouncer) => { // Appelé après chaque tentative d'exécution - console.log('Fonction async terminée', debouncer.getSettledCount()) + console.log('Fonction asynchrone terminée', debouncer.getSettledCount()) }, onError: (error) => { - // Appelé si la fonction async génère une erreur - console.error('Échec de la fonction async :', error) + // Appelé si la fonction asynchrone génère une erreur + console.error('Échec de la fonction asynchrone:', error) } }) ``` -Le callback `onSuccess` est appelé après chaque exécution réussie de la fonction débouncée, tandis que le callback `onError` est appelé si la fonction asynchrone génère une erreur. Le callback `onSettled` est appelé après chaque tentative d'exécution, qu'elle réussisse ou échoue. Ces callbacks sont particulièrement utiles pour suivre les compteurs d'exécution, mettre à jour l'état de l'UI, gérer les erreurs, effectuer des opérations de nettoyage et enregistrer des métriques d'exécution. +Le callback `onSuccess` est appelé après chaque exécution réussie de la fonction avec *débounce*, tandis que le callback `onError` est appelé si la fonction asynchrone génère une erreur. Le callback `onSettled` est appelé après chaque tentative d'exécution, qu'elle réussisse ou échoue. Ces callbacks sont particulièrement utiles pour suivre les compteurs d'exécution, mettre à jour l'état de l'interface, gérer les erreurs, effectuer des opérations de nettoyage et enregistrer des métriques d'exécution. -### Débounçage Asynchrone +### Débounce asynchrone -Le débounçage asynchrone offre un moyen puissant de gérer des opérations asynchrones avec débounçage, présentant plusieurs avantages clés par rapport à la version synchrone. Alors que le débounçage synchrone est idéal pour les événements UI et le retour immédiat, la version asynchrone est spécialement conçue pour gérer les appels API, les opérations de base de données et autres tâches asynchrones. +Le *debouncer* asynchrone offre un moyen puissant de gérer des opérations asynchrones avec *débounce*, présentant plusieurs avantages clés par rapport à la version synchrone. Alors que le *debouncer* synchrone est idéal pour les événements d'interface et les retours immédiats, la version asynchrone est spécialement conçue pour gérer les appels API, les opérations de base de données et d'autres tâches asynchrones. -#### Différences Clés par Rapport au Débounçage Synchrone +#### Différences clés avec le Débounce synchrone -1. **Gestion des Valeurs de Retour** -Contrairement au débounçage synchrone qui retourne void, la version asynchrone vous permet de capturer et d'utiliser la valeur de retour de votre fonction débouncée. Ceci est particulièrement utile lorsque vous devez travailler avec les résultats d'appels API ou d'autres opérations asynchrones. La méthode `maybeExecute` retourne une Promise qui se résout avec la valeur de retour de la fonction, vous permettant d'attendre le résultat et de le gérer de manière appropriée. +1. **Gestion des valeurs de retour** +Contrairement au *debouncer* synchrone qui renvoie void, la version asynchrone vous permet de capturer et d'utiliser la valeur de retour de votre fonction avec *débounce*. Ceci est particulièrement utile lorsque vous devez travailler avec les résultats d'appels API ou d'autres opérations asynchrones. La méthode `maybeExecute` renvoie une Promise qui se résout avec la valeur de retour de la fonction, vous permettant d'attendre le résultat et de le traiter de manière appropriée. -2. **Système de Callback Amélioré** -Le débounçage asynchrone fournit un système de callback plus sophistiqué que le simple callback `onExecute` de la version synchrone. Ce système inclut : -- `onSuccess` : Appelé lorsque la fonction async se termine avec succès, fournissant à la fois le résultat et l'instance du débounçage -- `onError` : Appelé lorsque la fonction async génère une erreur, fournissant à la fois l'erreur et l'instance du débounçage -- `onSettled` : Appelé après chaque tentative d'exécution, qu'elle réussisse ou échoue +2. **Callbacks différents** +L'`AsyncDebouncer` prend en charge les callbacks suivants au lieu du seul `onExecute` dans la version synchrone : +- `onSuccess` : Appelé après chaque exécution réussie, fournissant l'instance du *debouncer* +- `onSettled` : Appelé après chaque exécution, fournissant l'instance du *debouncer* +- `onError` : Appelé si la fonction asynchrone génère une erreur, fournissant à la fois l'erreur et l'instance du *debouncer* -3. **Suivi des Exécutions** -Le débounçage asynchrone fournit un suivi complet des exécutions via plusieurs méthodes : -- `getSuccessCount()` : Nombre d'exécutions réussies -- `getErrorCount()` : Nombre d'exécutions échouées -- `getSettledCount()` : Nombre total d'exécutions terminées (succès + échec) +3. **Exécution séquentielle** +Puisque la méthode `maybeExecute` du *debouncer* renvoie une Promise, vous pouvez choisir d'attendre chaque exécution avant de démarrer la suivante. Cela vous donne le contrôle sur l'ordre d'exécution et garantit que chaque appel traite les données les plus à jour. Ceci est particulièrement utile lorsque vous traitez des opérations qui dépendent des résultats d'appels précédents ou lorsque la cohérence des données est critique. -4. **Exécution Séquentielle** -Le débounçage asynchrone garantit que les exécutions suivantes attendent la fin de l'appel précédent avant de démarrer. Cela empêche les exécutions désordonnées et garantit que chaque appel traite les données les plus à jour. Ceci est particulièrement important lors de la gestion d'opérations dépendant des résultats d'appels précédents ou lorsque la cohérence des données est critique. +Par exemple, si vous mettez à jour le profil d'un utilisateur puis récupérez immédiatement ses données mises à jour, vous pouvez attendre l'opération de mise à jour avant de démarrer la récupération : -Par exemple, si vous mettez à jour le profil d'un utilisateur puis récupérez immédiatement ses données mises à jour, le débounçage asynchrone garantira que l'opération de récupération attend la fin de la mise à jour, évitant les conditions de course où vous pourriez obtenir des données obsolètes. +#### Exemple d'utilisation basique -#### Exemple d'Utilisation Basique - -Voici un exemple basique montrant comment utiliser le débounçage asynchrone pour une opération de recherche : +Voici un exemple basique montrant comment utiliser le *debouncer* asynchrone pour une opération de recherche : ```ts const debouncedSearch = asyncDebounce( @@ -232,10 +226,10 @@ const debouncedSearch = asyncDebounce( { wait: 500, onSuccess: (results, debouncer) => { - console.log('Recherche réussie :', results) + console.log('Recherche réussie:', results) }, onError: (error, debouncer) => { - console.error('Recherche échouée :', error) + console.error('Échec de la recherche:', error) } } ) @@ -244,22 +238,9 @@ const debouncedSearch = asyncDebounce( const results = await debouncedSearch('query') ``` -#### Modèles Avancés - -Le débounçage asynchrone peut être combiné avec divers modèles pour résoudre des problèmes complexes : - -1. **Intégration avec la Gestion d'État** -Lors de l'utilisation du débounçage asynchrone avec des systèmes de gestion d'état (comme useState de React ou createSignal de Solid), vous pouvez créer des modèles puissants pour gérer les états de chargement, les états d'erreur et les mises à jour de données. Les callbacks du débounçage fournissent des hooks parfaits pour mettre à jour l'état de l'UI en fonction du succès ou de l'échec des opérations. - -2. **Prévention des Conditions de Course** -Le modèle de mutation à vol unique (single-flight mutation) prévient naturellement les conditions de course dans de nombreux scénarios. Lorsque plusieurs parties de votre application tentent de mettre à jour la même ressource simultanément, le débounçage garantit que seule la mise à jour la plus récente se produit réellement, tout en fournissant des résultats à tous les appelants. - -3. **Récupération après Erreur** -Les capacités de gestion d'erreur du débounçage asynchrone le rendent idéal pour implémenter des logiques de réessai et des modèles de récupération après erreur. Vous pouvez utiliser le callback `onError` pour implémenter des stratégies personnalisées de gestion d'erreur, comme un backoff exponentiel ou des mécanismes de repli. +### Adaptateurs pour frameworks -### Adaptateurs pour Frameworks - -Chaque adaptateur de framework fournit des hooks qui s'appuient sur la fonctionnalité de base du débounçage pour s'intégrer avec le système de gestion d'état du framework. Des hooks comme `createDebouncer`, `useDebouncedCallback`, `useDebouncedState` ou `useDebouncedValue` sont disponibles pour chaque framework. +Chaque adaptateur de framework fournit des hooks qui s'appuient sur les fonctionnalités de base du *débounce* pour s'intégrer au système de gestion d'état du framework. Des hooks comme `createDebouncer`, `useDebouncedCallback`, `useDebouncedState` ou `useDebouncedValue` sont disponibles pour chaque framework. Voici quelques exemples : @@ -280,7 +261,7 @@ const handleSearch = useDebouncedCallback( { wait: 500 } ) -// Hook basé sur l'état pour une gestion d'état réactive +// Hook basé sur l'état pour la gestion d'état réactive const [instantState, setInstantState] = useState('') const [debouncedValue] = useDebouncedValue( instantState, // Valeur à débouncer @@ -302,4 +283,8 @@ const debouncer = createDebouncer( // Hook basé sur les signaux pour la gestion d'état const [searchTerm, setSearchTerm, debouncer] = createDebouncedSignal('', { wait: 500, - onExecute: (deb + onExecute: (debouncer) => { + console.log('Exécutions totales:', debouncer.getExecutionCount()) + } +}) +``` diff --git a/docs/fr/guides/rate-limiting.md b/docs/fr/guides/rate-limiting.md index 3dd0ce707..bf1a4b9a7 100644 --- a/docs/fr/guides/rate-limiting.md +++ b/docs/fr/guides/rate-limiting.md @@ -1,21 +1,21 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:17:19.300Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:59:35.579Z' title: Guide sur la limitation de débit id: rate-limiting --- -# Guide de limitation de débit (Rate Limiting) +# Guide sur la limitation de débit (Rate Limiting) -La limitation de débit (Rate Limiting), le throttling et le debouncing sont trois approches distinctes pour contrôler la fréquence d'exécution des fonctions. Chaque technique bloque les exécutions différemment, les rendant "lossy" - ce qui signifie que certains appels de fonction ne s'exécuteront pas lorsqu'ils sont demandés trop fréquemment. Comprendre quand utiliser chaque approche est crucial pour construire des applications performantes et fiables. Ce guide couvrira les concepts de limitation de débit (Rate Limiting) de TanStack Pacer. +La limitation de débit (Rate Limiting), l'étranglement (Throttling) et l'anti-rebond (Debouncing) sont trois approches distinctes pour contrôler la fréquence d'exécution des fonctions. Chaque technique bloque les exécutions différemment, les rendant "avec perte" (lossy) - ce qui signifie que certains appels de fonction ne s'exécuteront pas lorsqu'ils sont demandés trop fréquemment. Comprendre quand utiliser chaque approche est crucial pour créer des applications performantes et fiables. Ce guide couvrira les concepts de limitation de débit de TanStack Pacer. > [!NOTE] -> TanStack Pacer est actuellement uniquement une bibliothèque front-end. Ce sont des utilitaires pour la limitation de débit (Rate Limiting) côté client. +> TanStack Pacer est actuellement uniquement une bibliothèque front-end. Ce sont des utilitaires pour la limitation de débit côté client. ## Concept de limitation de débit (Rate Limiting) -La limitation de débit (Rate Limiting) est une technique qui limite la fréquence à laquelle une fonction peut s'exécuter sur une fenêtre de temps spécifique. Elle est particulièrement utile pour les scénarios où vous souhaitez empêcher une fonction d'être appelée trop fréquemment, comme lors de la gestion de requêtes API ou d'autres appels à des services externes. C'est l'approche la plus *naïve*, car elle permet aux exécutions de se produire par rafales jusqu'à ce que le quota soit atteint. +La limitation de débit est une technique qui limite la vitesse à laquelle une fonction peut s'exécuter sur une fenêtre de temps spécifique. Elle est particulièrement utile pour les scénarios où vous souhaitez empêcher une fonction d'être appelée trop fréquemment, comme lors de la gestion de requêtes API ou d'autres appels à des services externes. C'est l'approche la plus *naïve*, car elle permet des exécutions en rafale jusqu'à ce que le quota soit atteint. -### Visualisation de la limitation de débit (Rate Limiting) +### Visualisation de la limitation de débit ```text Rate Limiting (limit: 3 calls per window) @@ -26,31 +26,60 @@ Executed: ✅ ✅ ✅ ❌ ❌ [=== 3 allowed ===][=== blocked until window ends ===][=== new window =======] ``` -### Quand utiliser la limitation de débit (Rate Limiting) +### Types de fenêtres -La limitation de débit (Rate Limiting) est particulièrement importante lors de la gestion d'opérations front-end qui pourraient accidentellement submerger vos services back-end ou causer des problèmes de performance dans le navigateur. +TanStack Pacer prend en charge deux types de fenêtres de limitation de débit : + +1. **Fenêtre fixe (Fixed Window)** (par défaut) + - Une fenêtre stricte qui se réinitialise après la période de la fenêtre + - Toutes les exécutions dans la fenêtre comptent dans la limite + - La fenêtre se réinitialise complètement après la période + - Peut entraîner un comportement en rafale aux limites des fenêtres + +2. **Fenêtre glissante (Sliding Window)** + - Une fenêtre roulante qui permet des exécutions lorsque les anciennes expirent + - Fournit un taux d'exécution plus constant dans le temps + - Mieux pour maintenir un flux constant d'exécutions + - Empêche le comportement en rafale aux limites des fenêtres + +Voici une visualisation de la limitation de débit avec fenêtre glissante : + +```text +Sliding Window Rate Limiting (limit: 3 calls per window) +Timeline: [1 second per tick] + Window 1 | Window 2 +Calls: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ +Executed: ✅ ✅ ✅ ❌ ✅ ✅ ✅ + [=== 3 allowed ===][=== oldest expires, new allowed ===][=== continues sliding =======] +``` + +La différence clé est qu'avec une fenêtre glissante, dès que l'exécution la plus ancienne expire, une nouvelle exécution est autorisée. Cela crée un flux d'exécutions plus constant par rapport à l'approche de fenêtre fixe. + +### Quand utiliser la limitation de débit + +La limitation de débit est particulièrement importante lors de la gestion d'opérations front-end qui pourraient accidentellement submerger vos services back-end ou causer des problèmes de performance dans le navigateur. Cas d'utilisation courants : -- Empêcher le spam accidentel d'API dû à des interactions utilisateur rapides (par exemple, clics sur un bouton ou soumissions de formulaire) -- Scénarios où un comportement par rafales est acceptable mais où vous souhaitez limiter le débit maximum +- Empêcher le spam accidentel d'API à partir d'interactions utilisateur rapides (par exemple, clics sur bouton ou soumissions de formulaire) +- Scénarios où un comportement en rafale est acceptable mais vous souhaitez limiter le taux maximum - Protection contre les boucles infinies accidentelles ou les opérations récursives -### Quand ne pas utiliser la limitation de débit (Rate Limiting) +### Quand ne pas utiliser la limitation de débit -La limitation de débit (Rate Limiting) est l'approche la plus naïve pour contrôler la fréquence d'exécution des fonctions. C'est la moins flexible et la plus restrictive des trois techniques. Envisagez d'utiliser le [throttling](../guides/throttling) ou le [debouncing](../guides/debouncing) pour des exécutions plus espacées. +La limitation de débit est l'approche la plus naïve pour contrôler la fréquence d'exécution des fonctions. C'est la moins flexible et la plus restrictive des trois techniques. Envisagez d'utiliser [l'étranglement (throttling)](../guides/throttling) ou [l'anti-rebond (debouncing)](../guides/debouncing) pour des exécutions plus espacées. > [!TIP] -> Vous ne voudrez probablement pas utiliser la "limitation de débit (Rate Limiting)" pour la plupart des cas d'utilisation. Envisagez plutôt d'utiliser le [throttling](../guides/throttling) ou le [debouncing](../guides/debouncing). +> Vous ne voulez probablement pas utiliser la "limitation de débit" pour la plupart des cas d'utilisation. Envisagez plutôt d'utiliser [l'étranglement (throttling)](../guides/throttling) ou [l'anti-rebond (debouncing)](../guides/debouncing). -La nature "lossy" de la limitation de débit (Rate Limiting) signifie également que certaines exécutions seront rejetées et perdues. Cela peut poser problème si vous devez vous assurer que toutes les exécutions réussissent toujours. Envisagez d'utiliser la [mise en file d'attente (queueing)](../guides/queueing) si vous avez besoin de vous assurer que toutes les exécutions sont en file d'attente pour être exécutées, mais avec un délai throttlé pour ralentir le taux d'exécution. +La nature "avec perte" (lossy) de la limitation de débit signifie également que certaines exécutions seront rejetées et perdues. Cela peut poser problème si vous devez vous assurer que toutes les exécutions réussissent toujours. Envisagez d'utiliser [la mise en file d'attente (queueing)](../guides/queueing) si vous avez besoin de vous assurer que toutes les exécutions sont mises en file d'attente pour être exécutées, mais avec un délai limité pour ralentir le taux d'exécution. -## Limitation de débit (Rate Limiting) dans TanStack Pacer +## Limitation de débit dans TanStack Pacer -TanStack Pacer fournit une limitation de débit (Rate Limiting) synchrone et asynchrone via les classes `RateLimiter` et `AsyncRateLimiter` respectivement (et leurs fonctions correspondantes `rateLimit` et `asyncRateLimit`). +TanStack Pacer fournit une limitation de débit synchrone et asynchrone via les classes `RateLimiter` et `AsyncRateLimiter` respectivement (et leurs fonctions correspondantes `rateLimit` et `asyncRateLimit`). ### Utilisation de base avec `rateLimit` -La fonction `rateLimit` est le moyen le plus simple d'ajouter une limitation de débit (Rate Limiting) à n'importe quelle fonction. Elle est parfaite pour la plupart des cas d'utilisation où vous avez juste besoin d'appliquer une limite simple. +La fonction `rateLimit` est le moyen le plus simple d'ajouter une limitation de débit à n'importe quelle fonction. Elle est parfaite pour la plupart des cas d'utilisation où vous avez juste besoin d'appliquer une limite simple. ```ts import { rateLimit } from '@tanstack/pacer' @@ -61,8 +90,9 @@ const rateLimitedApi = rateLimit( { limit: 5, window: 60 * 1000, // 1 minute en millisecondes + windowType: 'fixed', // par défaut onReject: (rateLimiter) => { - console.log(`Limite de débit (Rate Limit) dépassée. Réessayez dans ${rateLimiter.getMsUntilNextWindow()}ms`) + console.log(`Limite de débit dépassée. Réessayez dans ${rateLimiter.getMsUntilNextWindow()}ms`) } } ) @@ -78,12 +108,12 @@ rateLimitedApi('user-6') // ❌ Rejeté jusqu'à la réinitialisation de la fen ### Utilisation avancée avec la classe `RateLimiter` -Pour des scénarios plus complexes où vous avez besoin d'un contrôle supplémentaire sur le comportement de limitation de débit (Rate Limiting), vous pouvez utiliser directement la classe `RateLimiter`. Cela vous donne accès à des méthodes et des informations d'état supplémentaires. +Pour des scénarios plus complexes où vous avez besoin d'un contrôle supplémentaire sur le comportement de limitation de débit, vous pouvez utiliser directement la classe `RateLimiter`. Cela vous donne accès à des méthodes et des informations d'état supplémentaires. ```ts import { RateLimiter } from '@tanstack/pacer' -// Créer une instance de limiteur de débit (Rate Limiter) +// Créer une instance de limiteur de débit const limiter = new RateLimiter( (id: string) => fetchUserData(id), { @@ -93,7 +123,7 @@ const limiter = new RateLimiter( console.log('Fonction exécutée', rateLimiter.getExecutionCount()) }, onReject: (rateLimiter) => { - console.log(`Limite de débit (Rate Limit) dépassée. Réessayez dans ${rateLimiter.getMsUntilNextWindow()}ms`) + console.log(`Limite de débit dépassée. Réessayez dans ${rateLimiter.getMsUntilNextWindow()}ms`) } } ) @@ -115,7 +145,10 @@ limiter.reset() ### Activation/Désactivation -La classe `RateLimiter` prend en charge l'activation/désactivation via l'option `enabled`. En utilisant la méthode `setOptions`, vous pouvez activer/désactiver le limiteur de débit (Rate Limiter) à tout moment : +La classe `RateLimiter` prend en charge l'activation/désactivation via l'option `enabled`. En utilisant la méthode `setOptions`, vous pouvez activer/désactiver le limiteur de débit à tout moment : + +> [!NOTE] +> L'option `enabled` active/désactive l'exécution réelle de la fonction. Désactiver le limiteur de débit ne désactive pas la limitation de débit, cela empêche simplement la fonction de s'exécuter. ```ts const limiter = new RateLimiter(fn, { @@ -126,15 +159,15 @@ const limiter = new RateLimiter(fn, { limiter.setOptions({ enabled: true }) // Activer à tout moment ``` -Si vous utilisez un adaptateur de framework où les options du limiteur de débit (Rate Limiter) sont réactives, vous pouvez définir l'option `enabled` sur une valeur conditionnelle pour activer/désactiver le limiteur de débit (Rate Limiter) à la volée. Cependant, si vous utilisez la fonction `rateLimit` ou la classe `RateLimiter` directement, vous devez utiliser la méthode `setOptions` pour modifier l'option `enabled`, car les options passées sont en fait transmises au constructeur de la classe `RateLimiter`. +Si vous utilisez un adaptateur de framework où les options du limiteur de débit sont réactives, vous pouvez définir l'option `enabled` sur une valeur conditionnelle pour activer/désactiver le limiteur de débit à la volée. Cependant, si vous utilisez directement la fonction `rateLimit` ou la classe `RateLimiter`, vous devez utiliser la méthode `setOptions` pour modifier l'option `enabled`, car les options passées sont en fait transmises au constructeur de la classe `RateLimiter`. -### Options de callback +### Options de rappel (Callbacks) -Les limiteurs de débit (Rate Limiters) synchrones et asynchrones prennent en charge des options de callback pour gérer différents aspects du cycle de vie de la limitation de débit (Rate Limiting) : +Les limiteurs de débit synchrones et asynchrones prennent en charge des options de rappel pour gérer différents aspects du cycle de vie de la limitation de débit : -#### Callbacks du limiteur de débit (Rate Limiter) synchrone +#### Rappels du limiteur de débit synchrone -Le `RateLimiter` synchrone prend en charge les callbacks suivants : +Le `RateLimiter` synchrone prend en charge les rappels suivants : ```ts const limiter = new RateLimiter(fn, { @@ -146,16 +179,16 @@ const limiter = new RateLimiter(fn, { }, onReject: (rateLimiter) => { // Appelé lorsqu'une exécution est rejetée - console.log(`Limite de débit (Rate Limit) dépassée. Réessayez dans ${rateLimiter.getMsUntilNextWindow()}ms`) + console.log(`Limite de débit dépassée. Réessayez dans ${rateLimiter.getMsUntilNextWindow()}ms`) } }) ``` -Le callback `onExecute` est appelé après chaque exécution réussie de la fonction avec limitation de débit (Rate Limited), tandis que le callback `onReject` est appelé lorsqu'une exécution est rejetée en raison de la limitation de débit (Rate Limiting). Ces callbacks sont utiles pour suivre les exécutions, mettre à jour l'état de l'interface utilisateur ou fournir des retours aux utilisateurs. +Le rappel `onExecute` est appelé après chaque exécution réussie de la fonction limitée, tandis que le rappel `onReject` est appelé lorsqu'une exécution est rejetée en raison de la limitation de débit. Ces rappels sont utiles pour suivre les exécutions, mettre à jour l'état de l'interface utilisateur ou fournir des retours aux utilisateurs. -#### Callbacks du limiteur de débit (Rate Limiter) asynchrone +#### Rappels du limiteur de débit asynchrone -Le `AsyncRateLimiter` asynchrone prend en charge des callbacks supplémentaires pour la gestion des erreurs : +Le `AsyncRateLimiter` asynchrone prend en charge des rappels supplémentaires pour la gestion des erreurs : ```ts const asyncLimiter = new AsyncRateLimiter(async (id) => { @@ -169,7 +202,7 @@ const asyncLimiter = new AsyncRateLimiter(async (id) => { }, onReject: (rateLimiter) => { // Appelé lorsqu'une exécution est rejetée - console.log(`Limite de débit (Rate Limit) dépassée. Réessayez dans ${rateLimiter.getMsUntilNextWindow()}ms`) + console.log(`Limite de débit dépassée. Réessayez dans ${rateLimiter.getMsUntilNextWindow()}ms`) }, onError: (error) => { // Appelé si la fonction asynchrone génère une erreur @@ -178,38 +211,33 @@ const asyncLimiter = new AsyncRateLimiter(async (id) => { }) ``` -Les callbacks `onExecute` et `onReject` fonctionnent de la même manière que dans le limiteur de débit (Rate Limiter) synchrone, tandis que le callback `onError` vous permet de gérer les erreurs avec élégance sans interrompre la chaîne de limitation de débit (Rate Limiting). Ces callbacks sont particulièrement utiles pour suivre les compteurs d'exécution, mettre à jour l'état de l'interface utilisateur, gérer les erreurs et fournir des retours aux utilisateurs. +Les rappels `onExecute` et `onReject` fonctionnent de la même manière que dans le limiteur de débit synchrone, tandis que le rappel `onError` vous permet de gérer les erreurs avec élégance sans interrompre la chaîne de limitation de débit. Ces rappels sont particulièrement utiles pour suivre les compteurs d'exécution, mettre à jour l'état de l'interface utilisateur, gérer les erreurs et fournir des retours aux utilisateurs. -### Limitation de débit (Rate Limiting) asynchrone +### Limitation de débit asynchrone -Le limiteur de débit (Rate Limiter) asynchrone offre un moyen puissant de gérer les opérations asynchrones avec limitation de débit (Rate Limiting), offrant plusieurs avantages clés par rapport à la version synchrone. Alors que le limiteur de débit (Rate Limiter) synchrone est idéal pour les événements d'interface utilisateur et les retours immédiats, la version asynchrone est spécialement conçue pour gérer les appels API, les opérations de base de données et d'autres tâches asynchrones. +Le limiteur de débit asynchrone fournit un moyen puissant de gérer les opérations asynchrones avec limitation de débit, offrant plusieurs avantages clés par rapport à la version synchrone. Alors que le limiteur de débit synchrone est idéal pour les événements d'interface utilisateur et les retours immédiats, la version asynchrone est spécialement conçue pour gérer les appels API, les opérations de base de données et d'autres tâches asynchrones. -#### Différences clés par rapport à la limitation de débit (Rate Limiting) synchrone +#### Différences clés par rapport à la limitation de débit synchrone 1. **Gestion des valeurs de retour** -Contrairement au limiteur de débit (Rate Limiter) synchrone qui retourne un booléen indiquant le succès, la version asynchrone vous permet de capturer et d'utiliser la valeur de retour de votre fonction avec limitation de débit (Rate Limited). Ceci est particulièrement utile lorsque vous devez travailler avec les résultats d'appels API ou d'autres opérations asynchrones. La méthode `maybeExecute` retourne une Promise qui se résout avec la valeur de retour de la fonction, vous permettant d'attendre le résultat et de le gérer de manière appropriée. +Contrairement au limiteur de débit synchrone qui renvoie un booléen indiquant le succès, la version asynchrone vous permet de capturer et d'utiliser la valeur de retour de votre fonction limitée. Ceci est particulièrement utile lorsque vous devez travailler avec les résultats d'appels API ou d'autres opérations asynchrones. La méthode `maybeExecute` renvoie une Promesse qui se résout avec la valeur de retour de la fonction, vous permettant d'attendre le résultat et de le gérer de manière appropriée. -2. **Système de callback amélioré** -Le limiteur de débit (Rate Limiter) asynchrone fournit un système de callback plus sophistiqué que les callbacks de la version synchrone. Ce système comprend : -- `onExecute` : Appelé après chaque exécution réussie, fournissant l'instance du limiteur de débit (Rate Limiter) -- `onReject` : Appelé lorsqu'une exécution est rejetée en raison de la limitation de débit (Rate Limiting), fournissant l'instance du limiteur de débit (Rate Limiter) -- `onError` : Appelé si la fonction asynchrone génère une erreur, fournissant à la fois l'erreur et l'instance du limiteur de débit (Rate Limiter) +2. **Rappels différents** +Le `AsyncRateLimiter` prend en charge les rappels suivants au lieu de simplement `onExecute` dans la version synchrone : +- `onSuccess` : Appelé après chaque exécution réussie, fournissant l'instance du limiteur de débit +- `onSettled` : Appelé après chaque exécution, fournissant l'instance du limiteur de débit +- `onError` : Appelé si la fonction asynchrone génère une erreur, fournissant à la fois l'erreur et l'instance du limiteur de débit -3. **Suivi des exécutions** -Le limiteur de débit (Rate Limiter) asynchrone fournit un suivi complet des exécutions via plusieurs méthodes : -- `getExecutionCount()` : Nombre d'exécutions réussies -- `getRejectionCount()` : Nombre d'exécutions rejetées -- `getRemainingInWindow()` : Nombre d'exécutions restantes dans la fenêtre actuelle -- `getMsUntilNextWindow()` : Millisecondes jusqu'au début de la prochaine fenêtre +Les deux limiteurs de débit asynchrone et synchrone prennent en charge le rappel `onReject` pour gérer les exécutions bloquées. -4. **Exécution séquentielle** -Le limiteur de débit (Rate Limiter) asynchrone garantit que les exécutions suivantes attendent la fin de l'appel précédent avant de commencer. Cela empêche les exécutions désordonnées et garantit que chaque appel traite les données les plus à jour. Ceci est particulièrement important lors de la gestion d'opérations qui dépendent des résultats d'appels précédents ou lorsque la cohérence des données est critique. +3. **Exécution séquentielle** +Puisque la méthode `maybeExecute` du limiteur de débit renvoie une Promesse, vous pouvez choisir d'attendre chaque exécution avant de commencer la suivante. Cela vous donne le contrôle sur l'ordre d'exécution et garantit que chaque appel traite les données les plus à jour. Ceci est particulièrement utile lors de la gestion d'opérations qui dépendent des résultats d'appels précédents ou lorsque la cohérence des données est critique. -Par exemple, si vous mettez à jour le profil d'un utilisateur et que vous récupérez immédiatement ses données mises à jour, le limiteur de débit (Rate Limiter) asynchrone garantira que l'opération de récupération attend la fin de la mise à jour, évitant ainsi les conditions de course où vous pourriez obtenir des données obsolètes. +Par exemple, si vous mettez à jour le profil d'un utilisateur et que vous récupérez immédiatement ses données mises à jour, vous pouvez attendre l'opération de mise à jour avant de lancer la récupération : #### Exemple d'utilisation de base -Voici un exemple de base montrant comment utiliser le limiteur de débit (Rate Limiter) asynchrone pour une opération API : +Voici un exemple de base montrant comment utiliser le limiteur de débit asynchrone pour une opération API : ```ts const rateLimitedApi = asyncRateLimit( @@ -224,7 +252,7 @@ const rateLimitedApi = asyncRateLimit( console.log('Appel API réussi :', limiter.getExecutionCount()) }, onReject: (limiter) => { - console.log(`Limite de débit (Rate Limit) dépassée. Réessayez dans ${limiter.getMsUntilNextWindow()}ms`) + console.log(`Limite de débit dépassée. Réessayez dans ${limiter.getMsUntilNextWindow()}ms`) }, onError: (error, limiter) => { console.error('Échec de l'appel API :', error) @@ -236,26 +264,38 @@ const rateLimitedApi = asyncRateLimit( const result = await rateLimitedApi('123') ``` -#### Modèles avancés +### Adaptateurs pour frameworks -Le limiteur de débit (Rate Limiter) asynchrone peut être combiné avec divers modèles pour résoudre des problèmes complexes : +Chaque adaptateur de framework fournit des hooks qui s'appuient sur la fonctionnalité de base de limitation de débit pour s'intégrer au système de gestion d'état du framework. Des hooks comme `createRateLimiter`, `useRateLimitedCallback`, `useRateLimitedState` ou `useRateLimitedValue` sont disponibles pour chaque framework. -1. **Intégration avec la gestion d'état** -Lorsque vous utilisez le limiteur de débit (Rate Limiter) asynchrone avec des systèmes de gestion d'état (comme useState de React ou createSignal de Solid), vous pouvez créer des modèles puissants pour gérer les états de chargement, les états d'erreur et les mises à jour de données. Les callbacks du limiteur de débit (Rate Limiter) fournissent des hooks parfaits pour mettre à jour l'état de l'interface utilisateur en fonction du succès ou de l'échec des opérations. +Voici quelques exemples : -2. **Prévention des conditions de course** -Le modèle de limitation de débit (Rate Limiting) prévient naturellement les conditions de course dans de nombreux scénarios. Lorsque plusieurs parties de votre application tentent de mettre à jour la même ressource simultanément, le limiteur de débit (Rate Limiter) garantit que les mises à jour se produisent dans les limites configurées, tout en fournissant des résultats à tous les appelants. +#### React -3. **Récupération après erreur** -Les capacités de gestion des erreurs du limiteur de débit (Rate Limiter) asynchrone en font un outil idéal pour implémenter une logique de réessai et des modèles de récupération après erreur. Vous pouvez utiliser le callback `onError` pour implémenter des stratégies de gestion d'erreur personnalisées, comme un backoff exponentiel ou des mécanismes de repli. +```tsx +import { useRateLimiter, useRateLimitedCallback, useRateLimitedValue } from '@tanstack/react-pacer' -### Adaptateurs de framework +// Hook bas niveau pour un contrôle complet +const limiter = useRateLimiter( + (id: string) => fetchUserData(id), + { limit: 5, window: 1000 } +) -Chaque adaptateur de framework fournit des hooks qui s'appuient sur les fonctionnalités de base de limitation de débit (Rate Limiting) pour s'intégrer au système de gestion d'état du framework. Des hooks comme `createRateLimiter`, `useRateLimitedCallback`, `useRateLimitedState` ou `useRateLimitedValue` sont disponibles pour chaque framework. +// Hook de rappel simple pour les cas d'utilisation de base +const handleFetch = useRateLimitedCallback( + (id: string) => fetchUserData(id), + { limit: 5, window: 1000 } +) -Voici quelques exemples : +// Hook basé sur l'état pour la gestion d'état réactive +const [instantState, setInstantState] = useState('') +const [rateLimitedValue] = useRateLimitedValue( + instantState, // Valeur à limiter + { limit: 5, window: 1000 } +) +``` -#### React +#### Solid ```tsx -import { useRateLimiter, useRateLimitedCallback, +import { createRateLimiter, createRateLimitedSignal } from diff --git a/docs/fr/guides/throttling.md b/docs/fr/guides/throttling.md index 312d9553f..79e2cfa54 100644 --- a/docs/fr/guides/throttling.md +++ b/docs/fr/guides/throttling.md @@ -1,66 +1,66 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:17:09.779Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:59:04.403Z' title: Guide sur le throttling id: throttling --- -# Guide sur la limitation de débit (Throttling) +# Guide sur le Throttling (Limitation de Fréquence) -La limitation de débit (Rate Limiting), la régulation (Throttling) et l'anti-rebond (Debouncing) sont trois approches distinctes pour contrôler la fréquence d'exécution des fonctions. Chaque technique bloque les exécutions différemment, les rendant "avec perte" - ce qui signifie que certains appels de fonction ne seront pas exécutés lorsqu'ils sont demandés trop fréquemment. Comprendre quand utiliser chaque approche est crucial pour créer des applications performantes et fiables. Ce guide couvrira les concepts de régulation (Throttling) de TanStack Pacer. +La limitation de débit (Rate Limiting), le throttling (limitation de fréquence) et le debouncing (anti-rebond) sont trois approches distinctes pour contrôler la fréquence d'exécution des fonctions. Chaque technique bloque les exécutions différemment, les rendant "lossy" (avec perte) - ce qui signifie que certains appels de fonction ne seront pas exécutés lorsqu'ils sont demandés trop fréquemment. Comprendre quand utiliser chaque approche est crucial pour créer des applications performantes et fiables. Ce guide couvrira les concepts de throttling de TanStack Pacer. -## Concept de régulation (Throttling) +## Concept de Throttling -La régulation (Throttling) garantit que les exécutions de fonctions sont uniformément espacées dans le temps. Contrairement à la limitation de débit (Rate Limiting) qui permet des rafales d'exécutions jusqu'à une limite, ou à l'anti-rebond (Debouncing) qui attend que l'activité s'arrête, la régulation crée un modèle d'exécution plus fluide en imposant des délais constants entre les appels. Si vous définissez une régulation d'une exécution par seconde, les appels seront espacés uniformément quelle que soit la rapidité avec laquelle ils sont demandés. +Le throttling garantit que les exécutions de fonction sont régulièrement espacées dans le temps. Contrairement à la limitation de débit qui permet des rafales d'exécutions jusqu'à une limite, ou au debouncing qui attend que l'activité s'arrête, le throttling crée un modèle d'exécution plus fluide en imposant des délais constants entre les appels. Si vous définissez un throttling d'une exécution par seconde, les appels seront espacés uniformément, quelle que soit la fréquence à laquelle ils sont demandés. -### Visualisation de la régulation (Throttling) +### Visualisation du Throttling ```text -Régulation (une exécution toutes les 3 unités de temps) -Chronologie: [1 seconde par unité] -Appels: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ -Exécutés: ✅ ❌ ⏳ -> ✅ ❌ ❌ ❌ ✅ ✅ +Throttling (one execution per 3 ticks) +Timeline: [1 second per tick] +Calls: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ +Executed: ✅ ❌ ⏳ -> ✅ ❌ ❌ ❌ ✅ ✅ [=================================================================] - ^ Seule une exécution autorisée toutes les 3 unités, - quel que soit le nombre d'appels effectués + ^ Only one execution allowed per 3 ticks, + regardless of how many calls are made - [Première rafale] [Plus d'appels] [Appels espacés] - Exécute le premier Exécute après Exécute chaque fois - puis régule la période d'attente que la période d'attente passe + [First burst] [More calls] [Spaced calls] + Execute first Execute after Execute each time + then throttle wait period wait period passes ``` -### Quand utiliser la régulation (Throttling) +### Quand Utiliser le Throttling -La régulation est particulièrement efficace lorsque vous avez besoin d'un timing d'exécution cohérent et prévisible. Cela la rend idéale pour gérer des événements ou des mises à jour fréquents où vous souhaitez un comportement fluide et contrôlé. +Le throttling est particulièrement efficace lorsque vous avez besoin d'une exécution cohérente et prévisible. Cela le rend idéal pour gérer des événements ou des mises à jour fréquents où vous souhaitez un comportement fluide et contrôlé. Cas d'utilisation courants : -- Mises à jour d'interface utilisateur nécessitant un timing cohérent (ex. : indicateurs de progression) +- Mises à jour d'interface utilisateur nécessitant un timing cohérent (par exemple, indicateurs de progression) - Gestionnaires d'événements de défilement ou de redimensionnement qui ne doivent pas submerger le navigateur -- Polling de données en temps réel où des intervalles constants sont souhaités +- Interrogation de données en temps réel où des intervalles constants sont souhaités - Opérations gourmandes en ressources nécessitant un rythme régulier -- Mises à jour de boucle de jeu ou gestion d'images d'animation +- Mises à jour de boucle de jeu ou gestion de trames d'animation - Suggestions de recherche en direct pendant la saisie utilisateur -### Quand ne pas utiliser la régulation (Throttling) +### Quand Ne Pas Utiliser le Throttling -La régulation pourrait ne pas être le meilleur choix lorsque : -- Vous voulez attendre que l'activité s'arrête (utilisez plutôt l'[anti-rebond](../guides/debouncing)) -- Vous ne pouvez pas vous permettre de manquer des exécutions (utilisez plutôt la [mise en file d'attente](../guides/queueing)) +Le throttling pourrait ne pas être le meilleur choix lorsque : +- Vous voulez attendre que l'activité s'arrête (utilisez plutôt le [debouncing](../guides/debouncing)) +- Vous ne pouvez pas vous permettre de manquer des exécutions (utilisez plutôt la [queueing](../guides/queueing)) > [!TIP] -> La régulation est souvent le meilleur choix lorsque vous avez besoin d'un timing d'exécution fluide et cohérent. Elle fournit un modèle d'exécution plus prévisible que la limitation de débit et un retour plus immédiat que l'anti-rebond. +> Le throttling est souvent le meilleur choix lorsque vous avez besoin d'un timing d'exécution fluide et cohérent. Il offre un modèle d'exécution plus prévisible que la limitation de débit et un retour plus immédiat que le debouncing. -## Régulation dans TanStack Pacer +## Throttling dans TanStack Pacer -TanStack Pacer fournit à la fois une régulation synchrone et asynchrone via les classes `Throttler` et `AsyncThrottler` respectivement (et leurs fonctions correspondantes `throttle` et `asyncThrottle`). +TanStack Pacer fournit à la fois du throttling synchrone et asynchrone via les classes `Throttler` et `AsyncThrottler` respectivement (et leurs fonctions correspondantes `throttle` et `asyncThrottle`). -### Utilisation basique avec `throttle` +### Utilisation Basique avec `throttle` -La fonction `throttle` est le moyen le plus simple d'ajouter une régulation à n'importe quelle fonction : +La fonction `throttle` est le moyen le plus simple d'ajouter du throttling à n'importe quelle fonction : ```ts import { throttle } from '@tanstack/pacer' -// Régule les mises à jour d'interface à une fois toutes les 200ms +// Limiter les mises à jour d'interface à une fois toutes les 200ms const throttledUpdate = throttle( (value: number) => updateProgressBar(value), { @@ -70,13 +70,13 @@ const throttledUpdate = throttle( // Dans une boucle rapide, n'exécute que toutes les 200ms for (let i = 0; i < 100; i++) { - throttledUpdate(i) // De nombreux appels sont régulés + throttledUpdate(i) // De nombreux appels sont throttlés } ``` -### Utilisation avancée avec la classe `Throttler` +### Utilisation Avancée avec la Classe `Throttler` -Pour plus de contrôle sur le comportement de régulation, vous pouvez utiliser directement la classe `Throttler` : +Pour plus de contrôle sur le comportement du throttling, vous pouvez utiliser directement la classe `Throttler` : ```ts import { Throttler } from '@tanstack/pacer' @@ -94,46 +94,46 @@ console.log(updateThrottler.getLastExecutionTime()) // Horodatage de la dernièr updateThrottler.cancel() ``` -### Exécutions en début et fin +### Exécutions Leading et Trailing -Le régulateur synchrone prend en charge les exécutions sur les fronts montant et descendant : +Le throttler synchrone prend en charge les exécutions sur les fronts montants (leading) et descendants (trailing) : ```ts const throttledFn = throttle(fn, { wait: 200, - leading: true, // Exécute au premier appel (par défaut) - trailing: true, // Exécute après la période d'attente (par défaut) + leading: true, // Exécuter au premier appel (par défaut) + trailing: true, // Exécuter après la période d'attente (par défaut) }) ``` -- `leading: true` (par défaut) - Exécute immédiatement au premier appel -- `leading: false` - Ignore le premier appel, attend l'exécution en fin -- `trailing: true` (par défaut) - Exécute le dernier appel après la période d'attente -- `trailing: false` - Ignore le dernier appel s'il est dans la période d'attente +- `leading: true` (par défaut) - Exécuter immédiatement au premier appel +- `leading: false` - Ignorer le premier appel, attendre l'exécution trailing +- `trailing: true` (par défaut) - Exécuter le dernier appel après la période d'attente +- `trailing: false` - Ignorer le dernier appel s'il est dans la période d'attente Modèles courants : - `{ leading: true, trailing: true }` - Par défaut, le plus réactif -- `{ leading: false, trailing: true }` - Retarde toutes les exécutions -- `{ leading: true, trailing: false }` - Ignore les exécutions en file d'attente +- `{ leading: false, trailing: true }` - Retarder toutes les exécutions +- `{ leading: true, trailing: false }` - Ignorer les exécutions en file d'attente ### Activation/Désactivation -La classe `Throttler` prend en charge l'activation/désactivation via l'option `enabled`. En utilisant la méthode `setOptions`, vous pouvez activer/désactiver le régulateur à tout moment : +La classe `Throttler` prend en charge l'activation/désactivation via l'option `enabled`. En utilisant la méthode `setOptions`, vous pouvez activer/désactiver le throttler à tout moment : ```ts const throttler = new Throttler(fn, { wait: 200, enabled: false }) // Désactivé par défaut -throttler.setOptions({ enabled: true }) // Active à tout moment +throttler.setOptions({ enabled: true }) // Activer à tout moment ``` -Si vous utilisez un adaptateur de framework où les options du régulateur sont réactives, vous pouvez définir l'option `enabled` sur une valeur conditionnelle pour activer/désactiver le régulateur à la volée. Cependant, si vous utilisez la fonction `throttle` ou la classe `Throttler` directement, vous devez utiliser la méthode `setOptions` pour modifier l'option `enabled`, car les options passées sont en fait transmises au constructeur de la classe `Throttler`. +Si vous utilisez un adaptateur de framework où les options du throttler sont réactives, vous pouvez définir l'option `enabled` sur une valeur conditionnelle pour activer/désactiver le throttler à la volée. Cependant, si vous utilisez la fonction `throttle` ou la classe `Throttler` directement, vous devez utiliser la méthode `setOptions` pour modifier l'option `enabled`, car les options passées sont en fait transmises au constructeur de la classe `Throttler`. -### Options de rappel +### Options de Callback -Les régulateurs synchrones et asynchrones prennent en charge des options de rappel pour gérer différents aspects du cycle de vie de la régulation : +Les throttlers synchrones et asynchrones prennent en charge des options de callback pour gérer différents aspects du cycle de vie du throttling : -#### Rappels du régulateur synchrone +#### Callbacks du Throttler Synchrone -Le `Throttler` synchrone prend en charge le rappel suivant : +Le `Throttler` synchrone prend en charge le callback suivant : ```ts const throttler = new Throttler(fn, { @@ -145,11 +145,11 @@ const throttler = new Throttler(fn, { }) ``` -Le rappel `onExecute` est appelé après chaque exécution réussie de la fonction régulée, ce qui le rend utile pour suivre les exécutions, mettre à jour l'état de l'interface ou effectuer des opérations de nettoyage. +Le callback `onExecute` est appelé après chaque exécution réussie de la fonction throttlée, ce qui le rend utile pour suivre les exécutions, mettre à jour l'état de l'interface ou effectuer des opérations de nettoyage. -#### Rappels du régulateur asynchrone +#### Callbacks du Throttler Asynchrone -Le `AsyncThrottler` asynchrone prend en charge des rappels supplémentaires pour la gestion des erreurs : +Le `AsyncThrottler` asynchrone prend en charge des callbacks supplémentaires pour la gestion des erreurs : ```ts const asyncThrottler = new AsyncThrottler(async (value) => { @@ -167,37 +167,33 @@ const asyncThrottler = new AsyncThrottler(async (value) => { }) ``` -Le rappel `onExecute` fonctionne de la même manière que dans le régulateur synchrone, tandis que le rappel `onError` vous permet de gérer les erreurs gracieusement sans interrompre la chaîne de régulation. Ces rappels sont particulièrement utiles pour suivre le nombre d'exécutions, mettre à jour l'état de l'interface, gérer les erreurs, effectuer des opérations de nettoyage et enregistrer des métriques d'exécution. +Le callback `onExecute` fonctionne de la même manière que dans le throttler synchrone, tandis que le callback `onError` vous permet de gérer les erreurs avec élégance sans interrompre la chaîne de throttling. Ces callbacks sont particulièrement utiles pour suivre les comptes d'exécution, mettre à jour l'état de l'interface, gérer les erreurs, effectuer des opérations de nettoyage et enregistrer des métriques d'exécution. -### Régulation asynchrone +### Throttling Asynchrone -Le régulateur asynchrone offre un moyen puissant de gérer les opérations asynchrones avec régulation, offrant plusieurs avantages clés par rapport à la version synchrone. Alors que le régulateur synchrone est idéal pour les événements d'interface et les retours immédiats, la version asynchrone est spécialement conçue pour gérer les appels d'API, les opérations de base de données et autres tâches asynchrones. +Le throttler asynchrone offre un moyen puissant de gérer les opérations asynchrones avec throttling, offrant plusieurs avantages clés par rapport à la version synchrone. Alors que le throttler synchrone est idéal pour les événements d'interface et les retours immédiats, la version asynchrone est spécialement conçue pour gérer les appels d'API, les opérations de base de données et autres tâches asynchrones. -#### Différences clés avec la régulation synchrone +#### Différences Clés par Rapport au Throttling Synchrone -1. **Gestion des valeurs de retour** -Contrairement au régulateur synchrone qui renvoie void, la version asynchrone vous permet de capturer et d'utiliser la valeur de retour de votre fonction régulée. Ceci est particulièrement utile lorsque vous devez travailler avec les résultats d'appels d'API ou d'autres opérations asynchrones. La méthode `maybeExecute` renvoie une Promise qui se résout avec la valeur de retour de la fonction, vous permettant d'attendre le résultat et de le gérer de manière appropriée. +1. **Gestion des Valeurs de Retour** +Contrairement au throttler synchrone qui renvoie void, la version asynchrone vous permet de capturer et d'utiliser la valeur de retour de votre fonction throttlée. Ceci est particulièrement utile lorsque vous devez travailler avec les résultats d'appels d'API ou d'autres opérations asynchrones. La méthode `maybeExecute` renvoie une Promise qui se résout avec la valeur de retour de la fonction, vous permettant d'attendre le résultat et de le gérer de manière appropriée. -2. **Système de rappel amélioré** -Le régulateur asynchrone fournit un système de rappel plus sophistiqué que le simple rappel `onExecute` de la version synchrone. Ce système comprend : -- `onSuccess` : Appelé lorsque la fonction asynchrone se termine avec succès, fournissant à la fois le résultat et l'instance du régulateur -- `onError` : Appelé lorsque la fonction asynchrone génère une erreur, fournissant à la fois l'erreur et l'instance du régulateur -- `onSettled` : Appelé après chaque tentative d'exécution, qu'elle réussisse ou échoue +2. **Callbacks Différents** +Le `AsyncThrottler` prend en charge les callbacks suivants au lieu du seul `onExecute` dans la version synchrone : +- `onSuccess` : Appelé après chaque exécution réussie, fournissant l'instance du throttler +- `onSettled` : Appelé après chaque exécution, fournissant l'instance du throttler +- `onError` : Appelé si la fonction asynchrone génère une erreur, fournissant à la fois l'erreur et l'instance du throttler -3. **Suivi des exécutions** -Le régulateur asynchrone fournit un suivi complet des exécutions via plusieurs méthodes : -- `getSuccessCount()` : Nombre d'exécutions réussies -- `getErrorCount()` : Nombre d'exécutions ayant échoué -- `getSettledCount()` : Nombre total d'exécutions terminées (succès + échec) +Les throttlers asynchrones et synchrones prennent tous deux en charge le callback `onExecute` pour gérer les exécutions réussies. -4. **Exécution séquentielle** -Le régulateur asynchrone garantit que les exécutions suivantes attendent la fin de l'appel précédent avant de commencer. Cela empêche les exécutions désordonnées et garantit que chaque appel traite les données les plus à jour. Ceci est particulièrement important lors de la gestion d'opérations qui dépendent des résultats d'appels précédents ou lorsque la cohérence des données est critique. +3. **Exécution Séquentielle** +Étant donné que la méthode `maybeExecute` du throttler renvoie une Promise, vous pouvez choisir d'attendre chaque exécution avant de démarrer la suivante. Cela vous donne le contrôle sur l'ordre d'exécution et garantit que chaque appel traite les données les plus à jour. Ceci est particulièrement utile lorsque vous traitez des opérations qui dépendent des résultats d'appels précédents ou lorsque la cohérence des données est critique. -Par exemple, si vous mettez à jour le profil d'un utilisateur puis récupérez immédiatement ses données mises à jour, le régulateur asynchrone garantira que l'opération de récupération attend la fin de la mise à jour, évitant ainsi les conditions de course où vous pourriez obtenir des données obsolètes. +Par exemple, si vous mettez à jour le profil d'un utilisateur et que vous récupérez immédiatement ses données mises à jour, vous pouvez attendre l'opération de mise à jour avant de démarrer la récupération : -#### Exemple d'utilisation basique +#### Exemple d'Utilisation Basique -Voici un exemple basique montrant comment utiliser le régulateur asynchrone pour une opération de recherche : +Voici un exemple basique montrant comment utiliser le throttler asynchrone pour une opération de recherche : ```ts const throttledSearch = asyncThrottle( @@ -211,7 +207,7 @@ const throttledSearch = asyncThrottle( console.log('Recherche réussie:', results) }, onError: (error, throttler) => { - console.error('Recherche échouée:', error) + console.error('Échec de la recherche:', error) } } ) @@ -220,22 +216,9 @@ const throttledSearch = asyncThrottle( const results = await throttledSearch('query') ``` -#### Modèles avancés +### Adaptateurs de Framework -Le régulateur asynchrone peut être combiné avec divers modèles pour résoudre des problèmes complexes : - -1. **Intégration avec la gestion d'état** -Lors de l'utilisation du régulateur asynchrone avec des systèmes de gestion d'état (comme useState de React ou createSignal de Solid), vous pouvez créer des modèles puissants pour gérer les états de chargement, les états d'erreur et les mises à jour de données. Les rappels du régulateur fournissent des crochets parfaits pour mettre à jour l'état de l'interface en fonction du succès ou de l'échec des opérations. - -2. **Prévention des conditions de course** -Le modèle de régulation empêche naturellement les conditions de course dans de nombreux scénarios. Lorsque plusieurs parties de votre application tentent de mettre à jour la même ressource simultanément, le régulateur garantit que les mises à jour se produisent à un rythme contrôlé, tout en fournissant des résultats à tous les appelants. - -3. **Récupération après erreur** -Les capacités de gestion des erreurs du régulateur asynchrone le rendent idéal pour implémenter une logique de réessai et des modèles de récupération après erreur. Vous pouvez utiliser le rappel `onError` pour implémenter des stratégies de gestion d'erreur personnalisées, comme un backoff exponentiel ou des mécanismes de repli. - -### Adaptateurs de framework - -Chaque adaptateur de framework fournit des hooks qui s'appuient sur la fonctionnalité de régulation de base pour s'intégrer au système de gestion d'état du framework. Des hooks comme `createThrottler`, `useThrottledCallback`, `useThrottledState` ou `useThrottledValue` sont disponibles pour chaque framework. +Chaque adaptateur de framework fournit des hooks qui s'appuient sur les fonctionnalités de base du throttling pour s'intégrer au système de gestion d'état du framework. Des hooks comme `createThrottler`, `useThrottledCallback`, `useThrottledState` ou `useThrottledValue` sont disponibles pour chaque framework. Voici quelques exemples : @@ -244,13 +227,13 @@ Voici quelques exemples : ```tsx import { useThrottler, useThrottledCallback, useThrottledValue } from '@tanstack/react-pacer' -// Hook bas niveau pour un contrôle complet +// Hook bas niveau pour un contrôle total const throttler = useThrottler( (value: number) => updateProgressBar(value), { wait: 200 } ) -// Hook de rappel simple pour les cas d'utilisation basiques +// Hook de callback simple pour les cas d'utilisation basiques const handleUpdate = useThrottledCallback( (value: number) => updateProgressBar(value), { wait: 200 } @@ -259,7 +242,7 @@ const handleUpdate = useThrottledCallback( // Hook basé sur l'état pour la gestion d'état réactive const [instantState, setInstantState] = useState(0) const [throttledValue] = useThrottledValue( - instantState, // Valeur à réguler + instantState, // Valeur à throttler { wait: 200 } ) ``` @@ -269,7 +252,7 @@ const [throttledValue] = useThrottledValue( ```tsx import { createThrottler, createThrottledSignal } from '@tanstack/solid-pacer' -// Hook bas niveau pour un contrôle complet +// Hook bas niveau pour un contrôle total const throttler = createThrottler( (value: number) => updateProgressBar(value), { wait: 200 } @@ -284,4 +267,4 @@ const [value, setValue, throttler] = createThrottledSignal(0, { }) ``` -Chaque adaptateur de framework fournit des hooks qui s'intègrent au système de gestion d'état du framework tout en conservant la fonctionnalité de régulation de base. +Chaque adaptateur de framework fournit des hooks qui s'intègrent au système de gestion d'état du framework tout en conservant les fonctionnalités de base du throttling. diff --git a/docs/fr/reference/classes/asyncdebouncer.md b/docs/fr/reference/classes/asyncdebouncer.md index 3045e5623..4e39928c6 100644 --- a/docs/fr/reference/classes/asyncdebouncer.md +++ b/docs/fr/reference/classes/asyncdebouncer.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:14:43.156Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:56:39.528Z' id: AsyncDebouncer title: AsyncDebouncer --- @@ -9,7 +9,7 @@ title: AsyncDebouncer # Class: AsyncDebouncer\ -Defined in: [async-debouncer.ts:73](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L73) +Defined in: [async-debouncer.ts:77](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L77) A class that creates an async debounced function. @@ -20,17 +20,21 @@ or input changes where you only want to execute the handler after the events hav Unlike throttling which allows execution at regular intervals, debouncing prevents any execution until the function stops being called for the specified delay period. +Unlike the non-async Debouncer, this async version supports returning values from the debounced function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the debounced function. + ## Example ```ts const asyncDebouncer = new AsyncDebouncer(async (value: string) => { - await searchAPI(value); + const results = await searchAPI(value); + return results; // Return value is preserved }, { wait: 500 }); // Called on each keystroke but only executes after 500ms of no typing -inputElement.addEventListener('input', () => { - asyncDebouncer.maybeExecute(inputElement.value); -}); +// Returns the API response directly +const results = await asyncDebouncer.maybeExecute(inputElement.value); ``` ## Type Parameters @@ -45,7 +49,7 @@ inputElement.addEventListener('input', () => { new AsyncDebouncer(fn, initialOptions): AsyncDebouncer ``` -Defined in: [async-debouncer.ts:86](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L86) +Defined in: [async-debouncer.ts:90](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L90) #### Parameters @@ -69,7 +73,7 @@ Defined in: [async-debouncer.ts:86](https://github.com/TanStack/pacer/blob/main/ cancel(): void ``` -Defined in: [async-debouncer.ts:195](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L195) +Defined in: [async-debouncer.ts:199](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L199) Cancels any pending execution or aborts any execution in progress @@ -85,7 +89,7 @@ Cancels any pending execution or aborts any execution in progress getErrorCount(): number ``` -Defined in: [async-debouncer.ts:224](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L224) +Defined in: [async-debouncer.ts:228](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L228) Returns the number of times the function has errored @@ -101,7 +105,7 @@ Returns the number of times the function has errored getIsExecuting(): boolean ``` -Defined in: [async-debouncer.ts:238](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L238) +Defined in: [async-debouncer.ts:242](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L242) Returns `true` if there is currently an execution in progress @@ -117,7 +121,7 @@ Returns `true` if there is currently an execution in progress getIsPending(): boolean ``` -Defined in: [async-debouncer.ts:231](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L231) +Defined in: [async-debouncer.ts:235](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L235) Returns `true` if there is a pending execution queued up for trailing execution @@ -133,7 +137,7 @@ Returns `true` if there is a pending execution queued up for trailing execution getLastResult(): undefined | ReturnType ``` -Defined in: [async-debouncer.ts:203](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L203) +Defined in: [async-debouncer.ts:207](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L207) Returns the last result of the debounced function @@ -149,7 +153,7 @@ Returns the last result of the debounced function getOptions(): Required> ``` -Defined in: [async-debouncer.ts:112](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L112) +Defined in: [async-debouncer.ts:116](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L116) Returns the current debouncer options @@ -165,7 +169,7 @@ Returns the current debouncer options getSettleCount(): number ``` -Defined in: [async-debouncer.ts:217](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L217) +Defined in: [async-debouncer.ts:221](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L221) Returns the number of times the function has settled (completed or errored) @@ -181,7 +185,7 @@ Returns the number of times the function has settled (completed or errored) getSuccessCount(): number ``` -Defined in: [async-debouncer.ts:210](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L210) +Defined in: [async-debouncer.ts:214](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L214) Returns the number of times the function has been executed successfully @@ -197,7 +201,7 @@ Returns the number of times the function has been executed successfully maybeExecute(...args): Promise> ``` -Defined in: [async-debouncer.ts:120](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L120) +Defined in: [async-debouncer.ts:124](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L124) Attempts to execute the debounced function If a call is already in progress, it will be queued @@ -220,7 +224,7 @@ If a call is already in progress, it will be queued setOptions(newOptions): void ``` -Defined in: [async-debouncer.ts:100](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L100) +Defined in: [async-debouncer.ts:104](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L104) Updates the debouncer options Returns the new options state diff --git a/docs/fr/reference/classes/asyncratelimiter.md b/docs/fr/reference/classes/asyncratelimiter.md index a694901fa..d64f80a58 100644 --- a/docs/fr/reference/classes/asyncratelimiter.md +++ b/docs/fr/reference/classes/asyncratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:14:43.147Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:56:39.524Z' id: AsyncRateLimiter title: AsyncRateLimiter --- @@ -9,7 +9,7 @@ title: AsyncRateLimiter # Class: AsyncRateLimiter\ -Defined in: [async-rate-limiter.ts:76](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L76) +Defined in: [async-rate-limiter.ts:95](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L95) A class that creates an async rate-limited function. @@ -17,6 +17,16 @@ Rate limiting is a simple approach that allows a function to execute up to a lim then blocks all subsequent calls until the window passes. This can lead to "bursty" behavior where all executions happen immediately, followed by a complete block. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + +Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + For smoother execution patterns, consider using: - Throttling: Ensures consistent spacing between executions (e.g. max once per 200ms) - Debouncing: Waits for a pause in calls before executing (e.g. after 500ms of no calls) @@ -29,11 +39,12 @@ smoothing out frequent events, throttling or debouncing usually provide better u ```ts const rateLimiter = new AsyncRateLimiter( async (id: string) => await api.getData(id), - { limit: 5, window: 1000 } // 5 calls per second + { limit: 5, window: 1000, windowType: 'sliding' } // 5 calls per second with sliding window ); // Will execute immediately until limit reached, then block -await rateLimiter.maybeExecute('123'); +// Returns the API response directly +const data = await rateLimiter.maybeExecute('123'); ``` ## Type Parameters @@ -48,7 +59,7 @@ await rateLimiter.maybeExecute('123'); new AsyncRateLimiter(fn, initialOptions): AsyncRateLimiter ``` -Defined in: [async-rate-limiter.ts:85](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L85) +Defined in: [async-rate-limiter.ts:105](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L105) #### Parameters @@ -72,7 +83,7 @@ Defined in: [async-rate-limiter.ts:85](https://github.com/TanStack/pacer/blob/ma getErrorCount(): number ``` -Defined in: [async-rate-limiter.ts:209](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L209) +Defined in: [async-rate-limiter.ts:250](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L250) Returns the number of times the function has errored @@ -82,15 +93,33 @@ Returns the number of times the function has errored *** +### getIsExecuting() + +```ts +getIsExecuting(): boolean +``` + +Defined in: [async-rate-limiter.ts:264](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L264) + +Returns whether the function is currently executing + +#### Returns + +`boolean` + +*** + ### getMsUntilNextWindow() ```ts getMsUntilNextWindow(): number ``` -Defined in: [async-rate-limiter.ts:188](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L188) +Defined in: [async-rate-limiter.ts:225](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L225) Returns the number of milliseconds until the next execution will be possible +For fixed windows, this is the time until the current window resets +For sliding windows, this is the time until the oldest execution expires #### Returns @@ -104,7 +133,7 @@ Returns the number of milliseconds until the next execution will be possible getOptions(): Required> ``` -Defined in: [async-rate-limiter.ts:106](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L106) +Defined in: [async-rate-limiter.ts:126](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L126) Returns the current rate limiter options @@ -120,7 +149,7 @@ Returns the current rate limiter options getRejectionCount(): number ``` -Defined in: [async-rate-limiter.ts:216](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L216) +Defined in: [async-rate-limiter.ts:257](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L257) Returns the number of times the function has been rejected @@ -136,7 +165,7 @@ Returns the number of times the function has been rejected getRemainingInWindow(): number ``` -Defined in: [async-rate-limiter.ts:180](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L180) +Defined in: [async-rate-limiter.ts:215](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L215) Returns the number of remaining executions allowed in the current window @@ -152,7 +181,7 @@ Returns the number of remaining executions allowed in the current window getSettleCount(): number ``` -Defined in: [async-rate-limiter.ts:202](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L202) +Defined in: [async-rate-limiter.ts:243](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L243) Returns the number of times the function has been settled @@ -168,7 +197,7 @@ Returns the number of times the function has been settled getSuccessCount(): number ``` -Defined in: [async-rate-limiter.ts:195](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L195) +Defined in: [async-rate-limiter.ts:236](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L236) Returns the number of times the function has been executed @@ -184,7 +213,7 @@ Returns the number of times the function has been executed maybeExecute(...args): Promise> ``` -Defined in: [async-rate-limiter.ts:126](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L126) +Defined in: [async-rate-limiter.ts:146](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L146) Attempts to execute the rate-limited function if within the configured limits. Will reject execution if the number of calls in the current window exceeds the limit. @@ -220,7 +249,7 @@ await rateLimiter.maybeExecute('arg1', 'arg2'); // Rejected reset(): void ``` -Defined in: [async-rate-limiter.ts:223](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L223) +Defined in: [async-rate-limiter.ts:271](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L271) Resets the rate limiter state @@ -236,7 +265,7 @@ Resets the rate limiter state setOptions(newOptions): void ``` -Defined in: [async-rate-limiter.ts:99](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L99) +Defined in: [async-rate-limiter.ts:119](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L119) Updates the rate limiter options Returns the new options state diff --git a/docs/fr/reference/classes/asyncthrottler.md b/docs/fr/reference/classes/asyncthrottler.md index be3e51e40..291bd7638 100644 --- a/docs/fr/reference/classes/asyncthrottler.md +++ b/docs/fr/reference/classes/asyncthrottler.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:14:43.143Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:56:39.520Z' id: AsyncThrottler title: AsyncThrottler --- @@ -9,7 +9,7 @@ title: AsyncThrottler # Class: AsyncThrottler\ -Defined in: [async-throttler.ts:76](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L76) +Defined in: [async-throttler.ts:80](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L80) A class that creates an async throttled function. @@ -17,6 +17,10 @@ Throttling limits how often a function can be executed, allowing only one execut Unlike debouncing which resets the delay timer on each call, throttling ensures the function executes at a regular interval regardless of how often it's called. +Unlike the non-async Throttler, this async version supports returning values from the throttled function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the throttled function. + This is useful for rate-limiting API calls, handling scroll/resize events, or any scenario where you want to ensure a maximum execution frequency. @@ -24,13 +28,13 @@ ensure a maximum execution frequency. ```ts const throttler = new AsyncThrottler(async (value: string) => { - await saveToAPI(value); + const result = await saveToAPI(value); + return result; // Return value is preserved }, { wait: 1000 }); // Will only execute once per second no matter how often called -inputElement.addEventListener('input', () => { - throttler.maybeExecute(inputElement.value); -}); +// Returns the API response directly +const result = await throttler.maybeExecute(inputElement.value); ``` ## Type Parameters @@ -45,7 +49,7 @@ inputElement.addEventListener('input', () => { new AsyncThrottler(fn, initialOptions): AsyncThrottler ``` -Defined in: [async-throttler.ts:89](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L89) +Defined in: [async-throttler.ts:93](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L93) #### Parameters @@ -69,7 +73,7 @@ Defined in: [async-throttler.ts:89](https://github.com/TanStack/pacer/blob/main/ cancel(): void ``` -Defined in: [async-throttler.ts:187](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L187) +Defined in: [async-throttler.ts:191](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L191) Cancels any pending execution or aborts any execution in progress @@ -85,7 +89,7 @@ Cancels any pending execution or aborts any execution in progress getErrorCount(): number ``` -Defined in: [async-throttler.ts:237](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L237) +Defined in: [async-throttler.ts:241](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L241) Returns the number of times the function has errored @@ -101,7 +105,7 @@ Returns the number of times the function has errored getIsExecuting(): boolean ``` -Defined in: [async-throttler.ts:251](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L251) +Defined in: [async-throttler.ts:255](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L255) Returns the current executing state @@ -117,7 +121,7 @@ Returns the current executing state getIsPending(): boolean ``` -Defined in: [async-throttler.ts:244](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L244) +Defined in: [async-throttler.ts:248](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L248) Returns the current pending state @@ -133,7 +137,7 @@ Returns the current pending state getLastExecutionTime(): number ``` -Defined in: [async-throttler.ts:202](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L202) +Defined in: [async-throttler.ts:206](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L206) Returns the last execution time @@ -149,7 +153,7 @@ Returns the last execution time getLastResult(): undefined | ReturnType ``` -Defined in: [async-throttler.ts:216](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L216) +Defined in: [async-throttler.ts:220](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L220) Returns the last result of the debounced function @@ -165,7 +169,7 @@ Returns the last result of the debounced function getNextExecutionTime(): number ``` -Defined in: [async-throttler.ts:209](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L209) +Defined in: [async-throttler.ts:213](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L213) Returns the next execution time @@ -181,7 +185,7 @@ Returns the next execution time getOptions(): Required> ``` -Defined in: [async-throttler.ts:115](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L115) +Defined in: [async-throttler.ts:119](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L119) Returns the current options @@ -197,7 +201,7 @@ Returns the current options getSettleCount(): number ``` -Defined in: [async-throttler.ts:230](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L230) +Defined in: [async-throttler.ts:234](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L234) Returns the number of times the function has settled (completed or errored) @@ -213,7 +217,7 @@ Returns the number of times the function has settled (completed or errored) getSuccessCount(): number ``` -Defined in: [async-throttler.ts:223](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L223) +Defined in: [async-throttler.ts:227](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L227) Returns the number of times the function has been executed successfully @@ -229,7 +233,7 @@ Returns the number of times the function has been executed successfully maybeExecute(...args): Promise> ``` -Defined in: [async-throttler.ts:123](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L123) +Defined in: [async-throttler.ts:127](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L127) Attempts to execute the throttled function If a call is already in progress, it may be blocked or queued depending on the `wait` option @@ -252,7 +256,7 @@ If a call is already in progress, it may be blocked or queued depending on the ` setOptions(newOptions): void ``` -Defined in: [async-throttler.ts:103](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L103) +Defined in: [async-throttler.ts:107](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L107) Updates the throttler options Returns the new options state diff --git a/docs/fr/reference/classes/ratelimiter.md b/docs/fr/reference/classes/ratelimiter.md index 7ba8ca92e..57c92e7ae 100644 --- a/docs/fr/reference/classes/ratelimiter.md +++ b/docs/fr/reference/classes/ratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:14:43.131Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:56:39.508Z' id: RateLimiter title: RateLimiter --- @@ -9,7 +9,7 @@ title: RateLimiter # Class: RateLimiter\ -Defined in: [rate-limiter.ts:63](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L63) +Defined in: [rate-limiter.ts:77](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L77) A class that creates a rate-limited function. @@ -17,6 +17,12 @@ Rate limiting is a simple approach that allows a function to execute up to a lim then blocks all subsequent calls until the window passes. This can lead to "bursty" behavior where all executions happen immediately, followed by a complete block. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns, consider using: - Throttling: Ensures consistent spacing between executions (e.g. max once per 200ms) - Debouncing: Waits for a pause in calls before executing (e.g. after 500ms of no calls) @@ -29,7 +35,7 @@ smoothing out frequent events, throttling or debouncing usually provide better u ```ts const rateLimiter = new RateLimiter( (id: string) => api.getData(id), - { limit: 5, window: 1000 } // 5 calls per second + { limit: 5, window: 1000, windowType: 'sliding' } // 5 calls per second with sliding window ); // Will execute immediately until limit reached, then block @@ -48,7 +54,7 @@ rateLimiter.maybeExecute('123'); new RateLimiter(fn, initialOptions): RateLimiter ``` -Defined in: [rate-limiter.ts:69](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L69) +Defined in: [rate-limiter.ts:83](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L83) #### Parameters @@ -72,7 +78,7 @@ Defined in: [rate-limiter.ts:69](https://github.com/TanStack/pacer/blob/main/pac getExecutionCount(): number ``` -Defined in: [rate-limiter.ts:149](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L149) +Defined in: [rate-limiter.ts:175](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L175) Returns the number of times the function has been executed @@ -88,7 +94,7 @@ Returns the number of times the function has been executed getMsUntilNextWindow(): number ``` -Defined in: [rate-limiter.ts:171](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L171) +Defined in: [rate-limiter.ts:197](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L197) Returns the number of milliseconds until the next execution will be possible @@ -104,7 +110,7 @@ Returns the number of milliseconds until the next execution will be possible getOptions(): Required> ``` -Defined in: [rate-limiter.ts:90](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L90) +Defined in: [rate-limiter.ts:104](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L104) Returns the current rate limiter options @@ -120,7 +126,7 @@ Returns the current rate limiter options getRejectionCount(): number ``` -Defined in: [rate-limiter.ts:156](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L156) +Defined in: [rate-limiter.ts:182](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L182) Returns the number of times the function has been rejected @@ -136,7 +142,7 @@ Returns the number of times the function has been rejected getRemainingInWindow(): number ``` -Defined in: [rate-limiter.ts:163](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L163) +Defined in: [rate-limiter.ts:189](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L189) Returns the number of remaining executions allowed in the current window @@ -152,7 +158,7 @@ Returns the number of remaining executions allowed in the current window maybeExecute(...args): boolean ``` -Defined in: [rate-limiter.ts:109](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L109) +Defined in: [rate-limiter.ts:123](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L123) Attempts to execute the rate-limited function if within the configured limits. Will reject execution if the number of calls in the current window exceeds the limit. @@ -187,7 +193,7 @@ rateLimiter.maybeExecute('arg1', 'arg2'); // false reset(): void ``` -Defined in: [rate-limiter.ts:179](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L179) +Defined in: [rate-limiter.ts:208](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L208) Resets the rate limiter state @@ -203,7 +209,7 @@ Resets the rate limiter state setOptions(newOptions): void ``` -Defined in: [rate-limiter.ts:83](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L83) +Defined in: [rate-limiter.ts:97](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L97) Updates the rate limiter options Returns the new options state diff --git a/docs/fr/reference/functions/asyncdebounce.md b/docs/fr/reference/functions/asyncdebounce.md index 7863f83d0..1f2a6dbef 100644 --- a/docs/fr/reference/functions/asyncdebounce.md +++ b/docs/fr/reference/functions/asyncdebounce.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-04-24T02:14:56.000Z' -translation-updated-at: '2025-05-06T20:43:04.119Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:56:39.504Z' id: asyncDebounce title: asyncDebounce --- @@ -10,21 +10,23 @@ title: asyncDebounce # Function: asyncDebounce() ```ts -function asyncDebounce(fn, initialOptions): (...args) => Promise +function asyncDebounce(fn, initialOptions): (...args) => Promise> ``` -Defined in: [async-debouncer.ts:219](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L219) +Defined in: [async-debouncer.ts:268](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L268) Creates an async debounced function that delays execution until after a specified wait time. The debounced function will only execute once the wait period has elapsed without any new calls. If called again during the wait period, the timer resets and a new wait period begins. +Unlike the non-async Debouncer, this async version supports returning values from the debounced function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the debounced function. + ## Type Parameters • **TFn** *extends* [`AnyAsyncFunction`](../type-aliases/anyasyncfunction.md) -• **TArgs** *extends* `any`[] - ## Parameters ### fn @@ -33,7 +35,7 @@ If called again during the wait period, the timer resets and a new wait period b ### initialOptions -`Omit`\<[`AsyncDebouncerOptions`](../interfaces/asyncdebounceroptions.md)\<`TFn`, `TArgs`\>, `"enabled"`\> +`Omit`\<[`AsyncDebouncerOptions`](../interfaces/asyncdebounceroptions.md)\<`TFn`\>, `"enabled"`\> ## Returns @@ -46,21 +48,21 @@ If a call is already in progress, it will be queued #### args -...`TArgs` +...`Parameters`\<`TFn`\> ### Returns -`Promise`\<`void`\> +`Promise`\<`undefined` \| `ReturnType`\<`TFn`\>\> ## Example ```ts const debounced = asyncDebounce(async (value: string) => { - await saveToAPI(value); + const result = await saveToAPI(value); + return result; // Return value is preserved }, { wait: 1000 }); // Will only execute once, 1 second after the last call -await debounced("first"); // Cancelled -await debounced("second"); // Cancelled -await debounced("third"); // Executes after 1s +// Returns the API response directly +const result = await debounced("third"); ``` diff --git a/docs/fr/reference/functions/asyncratelimit.md b/docs/fr/reference/functions/asyncratelimit.md index 6c6bc9f21..272968a97 100644 --- a/docs/fr/reference/functions/asyncratelimit.md +++ b/docs/fr/reference/functions/asyncratelimit.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:14:43.123Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:56:39.501Z' id: asyncRateLimit title: asyncRateLimit --- @@ -13,10 +13,20 @@ title: asyncRateLimit function asyncRateLimit(fn, initialOptions): (...args) => Promise> ``` -Defined in: [async-rate-limiter.ts:262](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L262) +Defined in: [async-rate-limiter.ts:322](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L322) Creates an async rate-limited function that will execute the provided function up to a maximum number of times within a time window. +Unlike the non-async rate limiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + Note that rate limiting is a simpler form of execution control compared to throttling or debouncing: - A rate limiter will allow all executions until the limit is reached, then block all subsequent calls until the window resets - A throttler ensures even spacing between executions, which can be better for consistent performance @@ -72,10 +82,11 @@ await rateLimiter.maybeExecute('arg1', 'arg2'); // Rejected ## Example ```ts -// Rate limit to 5 calls per minute +// Rate limit to 5 calls per minute with a sliding window const rateLimited = asyncRateLimit(makeApiCall, { limit: 5, window: 60000, + windowType: 'sliding', onReject: (rateLimiter) => { console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } @@ -83,7 +94,8 @@ const rateLimited = asyncRateLimit(makeApiCall, { // First 5 calls will execute immediately // Additional calls will be rejected until the minute window resets -await rateLimited(); +// Returns the API response directly +const result = await rateLimited(); // For more even execution, consider using throttle instead: const throttled = throttle(makeApiCall, { wait: 12000 }); // One call every 12 seconds diff --git a/docs/fr/reference/functions/asyncthrottle.md b/docs/fr/reference/functions/asyncthrottle.md index 22884ed66..15186c29b 100644 --- a/docs/fr/reference/functions/asyncthrottle.md +++ b/docs/fr/reference/functions/asyncthrottle.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-04-24T02:14:56.000Z' -translation-updated-at: '2025-05-06T20:43:04.110Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:56:39.497Z' id: asyncThrottle title: asyncThrottle --- @@ -10,21 +10,23 @@ title: asyncThrottle # Function: asyncThrottle() ```ts -function asyncThrottle(fn, initialOptions): (...args) => Promise +function asyncThrottle(fn, initialOptions): (...args) => Promise> ``` -Defined in: [async-throttler.ts:223](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L223) +Defined in: [async-throttler.ts:281](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L281) Creates an async throttled function that limits how often the function can execute. The throttled function will execute at most once per wait period, even if called multiple times. If called while executing, it will wait until execution completes before scheduling the next call. +Unlike the non-async Throttler, this async version supports returning values from the throttled function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the throttled function. + ## Type Parameters • **TFn** *extends* [`AnyAsyncFunction`](../type-aliases/anyasyncfunction.md) -• **TArgs** *extends* `any`[] - ## Parameters ### fn @@ -33,7 +35,7 @@ If called while executing, it will wait until execution completes before schedul ### initialOptions -`Omit`\<[`AsyncThrottlerOptions`](../interfaces/asyncthrottleroptions.md)\<`TFn`, `TArgs`\>, `"enabled"`\> +`Omit`\<[`AsyncThrottlerOptions`](../interfaces/asyncthrottleroptions.md)\<`TFn`\>, `"enabled"`\> ## Returns @@ -46,20 +48,21 @@ If a call is already in progress, it may be blocked or queued depending on the ` #### args -...`TArgs` +...`Parameters`\<`TFn`\> ### Returns -`Promise`\<`void`\> +`Promise`\<`undefined` \| `ReturnType`\<`TFn`\>\> ## Example ```ts -const throttled = asyncThrottle(async () => { - await someAsyncOperation(); +const throttled = asyncThrottle(async (value: string) => { + const result = await saveToAPI(value); + return result; // Return value is preserved }, { wait: 1000 }); // This will execute at most once per second -await throttled(); -await throttled(); // Waits 1 second before executing +// Returns the API response directly +const result = await throttled(inputElement.value); ``` diff --git a/docs/fr/reference/functions/ratelimit.md b/docs/fr/reference/functions/ratelimit.md index 391b587f7..87ba516fe 100644 --- a/docs/fr/reference/functions/ratelimit.md +++ b/docs/fr/reference/functions/ratelimit.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:14:43.115Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:56:39.493Z' id: rateLimit title: rateLimit --- @@ -13,7 +13,7 @@ title: rateLimit function rateLimit(fn, initialOptions): (...args) => boolean ``` -Defined in: [rate-limiter.ts:216](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L216) +Defined in: [rate-limiter.ts:252](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L252) Creates a rate-limited function that will execute the provided function up to a maximum number of times within a time window. @@ -22,6 +22,12 @@ Note that rate limiting is a simpler form of execution control compared to throt - A throttler ensures even spacing between executions, which can be better for consistent performance - A debouncer collapses multiple calls into one, which is better for handling bursts of events +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + Consider using throttle() or debounce() if you need more intelligent execution control. Use rate limiting when you specifically need to enforce a hard limit on the number of executions within a time period. @@ -71,10 +77,11 @@ rateLimiter.maybeExecute('arg1', 'arg2'); // false ## Example ```ts -// Rate limit to 5 calls per minute +// Rate limit to 5 calls per minute with a sliding window const rateLimited = rateLimit(makeApiCall, { limit: 5, window: 60000, + windowType: 'sliding', onReject: (rateLimiter) => { console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/fr/reference/interfaces/asyncratelimiteroptions.md b/docs/fr/reference/interfaces/asyncratelimiteroptions.md index e3973101f..cc62e2c62 100644 --- a/docs/fr/reference/interfaces/asyncratelimiteroptions.md +++ b/docs/fr/reference/interfaces/asyncratelimiteroptions.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:14:43.098Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:56:39.489Z' id: AsyncRateLimiterOptions title: AsyncRateLimiterOptions --- @@ -149,3 +149,18 @@ window: number; Defined in: [async-rate-limiter.ts:38](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L38) Time window in milliseconds within which the limit applies + +*** + +### windowType? + +```ts +optional windowType: "fixed" | "sliding"; +``` + +Defined in: [async-rate-limiter.ts:45](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L45) + +Type of window to use for rate limiting +- 'fixed': Uses a fixed window that resets after the window period +- 'sliding': Uses a sliding window that allows executions as old ones expire +Defaults to 'fixed' diff --git a/docs/fr/reference/interfaces/ratelimiteroptions.md b/docs/fr/reference/interfaces/ratelimiteroptions.md index a4f059371..3f734c677 100644 --- a/docs/fr/reference/interfaces/ratelimiteroptions.md +++ b/docs/fr/reference/interfaces/ratelimiteroptions.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:14:43.069Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:56:39.486Z' id: RateLimiterOptions title: RateLimiterOptions --- @@ -97,3 +97,18 @@ window: number; Defined in: [rate-limiter.ts:27](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L27) Time window in milliseconds within which the limit applies + +*** + +### windowType? + +```ts +optional windowType: "fixed" | "sliding"; +``` + +Defined in: [rate-limiter.ts:34](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L34) + +Type of window to use for rate limiting +- 'fixed': Uses a fixed window that resets after the window period +- 'sliding': Uses a sliding window that allows executions as old ones expire +Defaults to 'fixed' diff --git a/docs/ja/framework/react/reference/functions/useasyncratelimiter.md b/docs/ja/framework/react/reference/functions/useasyncratelimiter.md index 431ab2871..c6913414d 100644 --- a/docs/ja/framework/react/reference/functions/useasyncratelimiter.md +++ b/docs/ja/framework/react/reference/functions/useasyncratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:06:43.748Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:47:46.108Z' id: useAsyncRateLimiter title: useAsyncRateLimiter --- @@ -13,7 +13,7 @@ title: useAsyncRateLimiter function useAsyncRateLimiter(fn, options): AsyncRateLimiter ``` -Defined in: [react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts:43](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts#L43) +Defined in: [react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts:54](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts#L54) A low-level React hook that creates an `AsyncRateLimiter` instance to limit how many times an async function can execute within a time window. @@ -24,6 +24,16 @@ Rate limiting allows an async function to execute up to a specified limit within then blocks subsequent calls until the window passes. This is useful for respecting API rate limits, managing resource constraints, or controlling bursts of async operations. +Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + ## Type Parameters • **TFn** *extends* `AnyAsyncFunction` @@ -45,21 +55,22 @@ managing resource constraints, or controlling bursts of async operations. ## Example ```tsx -// Basic API call rate limiting +// Basic API call rate limiting with return value const { maybeExecute } = useAsyncRateLimiter( async (id: string) => { const data = await api.fetchData(id); - return data; + return data; // Return value is preserved }, { limit: 5, window: 1000 } // 5 calls per second ); -// With state management +// With state management and return value const [data, setData] = useState(null); const { maybeExecute } = useAsyncRateLimiter( async (query) => { const result = await searchAPI(query); setData(result); + return result; // Return value can be used by the caller }, { limit: 10, diff --git a/docs/ja/framework/react/reference/functions/useratelimitedcallback.md b/docs/ja/framework/react/reference/functions/useratelimitedcallback.md index 1fcdfac0e..6225ded37 100644 --- a/docs/ja/framework/react/reference/functions/useratelimitedcallback.md +++ b/docs/ja/framework/react/reference/functions/useratelimitedcallback.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-04-24T02:14:56.000Z' -translation-updated-at: '2025-05-06T20:30:24.139Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:47:46.103Z' id: useRateLimitedCallback title: useRateLimitedCallback --- @@ -13,7 +13,7 @@ title: useRateLimitedCallback function useRateLimitedCallback(fn, options): (...args) => boolean ``` -Defined in: [rate-limiter/useRateLimitedCallback.ts:52](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedCallback.ts#L52) +Defined in: [react-pacer/src/rate-limiter/useRateLimitedCallback.ts:59](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedCallback.ts#L59) A React hook that creates a rate-limited version of a callback function. This hook is essentially a wrapper around the basic `rateLimiter` function @@ -26,6 +26,12 @@ or debouncing, it does not attempt to space out or intelligently collapse calls. This can lead to bursts of rapid executions followed by periods where all calls are blocked. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns, consider: - useThrottledCallback: When you want consistent spacing between executions (e.g. UI updates) - useDebouncedCallback: When you want to collapse rapid calls into a single execution (e.g. search input) @@ -57,7 +63,7 @@ Consider using the `useRateLimiter` hook instead. ### options -`RateLimiterOptions`\<`TFn`, `TArgs`\> +`RateLimiterOptions`\<`TFn`\> ## Returns @@ -76,7 +82,7 @@ Consider using the `useRateLimiter` hook instead. ## Example ```tsx -// Rate limit API calls to maximum 5 calls per minute +// Rate limit API calls to maximum 5 calls per minute with a sliding window const makeApiCall = useRateLimitedCallback( (data: ApiData) => { return fetch('/api/endpoint', { method: 'POST', body: JSON.stringify(data) }); @@ -84,6 +90,7 @@ const makeApiCall = useRateLimitedCallback( { limit: 5, window: 60000, // 1 minute + windowType: 'sliding', onReject: () => { console.warn('API rate limit reached. Please wait before trying again.'); } diff --git a/docs/ja/framework/react/reference/functions/useratelimitedstate.md b/docs/ja/framework/react/reference/functions/useratelimitedstate.md index c1fff71ab..c1559b89b 100644 --- a/docs/ja/framework/react/reference/functions/useratelimitedstate.md +++ b/docs/ja/framework/react/reference/functions/useratelimitedstate.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:06:43.711Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:47:46.100Z' id: useRateLimitedState title: useRateLimitedState --- @@ -13,7 +13,7 @@ title: useRateLimitedState function useRateLimitedState(value, options): [TValue, Dispatch>, RateLimiter>>] ``` -Defined in: [react-pacer/src/rate-limiter/useRateLimitedState.ts:59](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedState.ts#L59) +Defined in: [react-pacer/src/rate-limiter/useRateLimitedState.ts:66](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedState.ts#L66) A React hook that creates a rate-limited state value that enforces a hard limit on state updates within a time window. This hook combines React's useState with rate limiting functionality to provide controlled state updates. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - useThrottledState: When you want consistent spacing between updates (e.g. UI changes) - useDebouncedState: When you want to collapse rapid updates into a single update (e.g. search input) @@ -57,16 +63,18 @@ consider using the lower-level useRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update state at most 5 times per minute +// Basic rate limiting - update state at most 5 times per minute with a sliding window const [value, setValue, rateLimiter] = useRateLimitedState(0, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); -// With rejection callback +// With rejection callback and fixed window const [value, setValue] = useRateLimitedState(0, { limit: 3, window: 5000, + windowType: 'fixed', onReject: (rateLimiter) => { alert(`Rate limit reached. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/ja/framework/react/reference/functions/useratelimitedvalue.md b/docs/ja/framework/react/reference/functions/useratelimitedvalue.md index dffd16048..f1130e8c8 100644 --- a/docs/ja/framework/react/reference/functions/useratelimitedvalue.md +++ b/docs/ja/framework/react/reference/functions/useratelimitedvalue.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:06:43.707Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:47:46.096Z' id: useRateLimitedValue title: useRateLimitedValue --- @@ -13,7 +13,7 @@ title: useRateLimitedValue function useRateLimitedValue(value, options): [TValue, RateLimiter>>] ``` -Defined in: [react-pacer/src/rate-limiter/useRateLimitedValue.ts:47](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedValue.ts#L47) +Defined in: [react-pacer/src/rate-limiter/useRateLimitedValue.ts:55](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedValue.ts#L55) A high-level React hook that creates a rate-limited version of a value that updates at most a certain number of times within a time window. This hook uses React's useState internally to manage the rate-limited state. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - useThrottledValue: When you want consistent spacing between updates (e.g. UI changes) - useDebouncedValue: When you want to collapse rapid updates into a single update (e.g. search input) @@ -56,16 +62,18 @@ consider using the lower-level useRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update at most 5 times per minute +// Basic rate limiting - update at most 5 times per minute with a sliding window const [rateLimitedValue, rateLimiter] = useRateLimitedValue(rawValue, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); -// With rejection callback +// With rejection callback and fixed window const [rateLimitedValue, rateLimiter] = useRateLimitedValue(rawValue, { limit: 3, window: 5000, + windowType: 'fixed', onReject: (rateLimiter) => { console.log(`Update rejected. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/ja/framework/react/reference/functions/useratelimiter.md b/docs/ja/framework/react/reference/functions/useratelimiter.md index 9ad7d4356..56b073e01 100644 --- a/docs/ja/framework/react/reference/functions/useratelimiter.md +++ b/docs/ja/framework/react/reference/functions/useratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:06:43.703Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:47:46.093Z' id: useRateLimiter title: useRateLimiter --- @@ -13,7 +13,7 @@ title: useRateLimiter function useRateLimiter(fn, options): RateLimiter ``` -Defined in: [react-pacer/src/rate-limiter/useRateLimiter.ts:48](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimiter.ts#L48) +Defined in: [react-pacer/src/rate-limiter/useRateLimiter.ts:55](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimiter.ts#L55) A low-level React hook that creates a `RateLimiter` instance to enforce rate limits on function execution. @@ -24,6 +24,12 @@ Rate limiting is a simple "hard limit" approach that allows executions until a m a time window, then blocks all subsequent calls until the window resets. Unlike throttling or debouncing, it does not attempt to space out or collapse executions intelligently. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns: - Use throttling when you want consistent spacing between executions (e.g. UI updates) - Use debouncing when you want to collapse rapid-fire events (e.g. search input) @@ -57,10 +63,11 @@ The hook returns an object containing: ## Example ```tsx -// Basic rate limiting - max 5 calls per minute +// Basic rate limiting - max 5 calls per minute with a sliding window const { maybeExecute } = useRateLimiter(apiCall, { limit: 5, window: 60000, + windowType: 'sliding', }); // Monitor rate limit status diff --git a/docs/ja/framework/solid/reference/functions/createasyncratelimiter.md b/docs/ja/framework/solid/reference/functions/createasyncratelimiter.md index 162768b3e..36b9f99e3 100644 --- a/docs/ja/framework/solid/reference/functions/createasyncratelimiter.md +++ b/docs/ja/framework/solid/reference/functions/createasyncratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:06:43.675Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:47:46.087Z' id: createAsyncRateLimiter title: createAsyncRateLimiter --- @@ -13,7 +13,7 @@ title: createAsyncRateLimiter function createAsyncRateLimiter(fn, initialOptions): SolidAsyncRateLimiter ``` -Defined in: [async-rate-limiter/createAsyncRateLimiter.ts:62](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L62) +Defined in: [async-rate-limiter/createAsyncRateLimiter.ts:73](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L73) A low-level Solid hook that creates an `AsyncRateLimiter` instance to limit how many times an async function can execute within a time window. @@ -24,6 +24,16 @@ Rate limiting allows an async function to execute up to a specified limit within then blocks subsequent calls until the window passes. This is useful for respecting API rate limits, managing resource constraints, or controlling bursts of async operations. +Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + ## Type Parameters • **TFn** *extends* `AnyAsyncFunction` @@ -45,21 +55,22 @@ managing resource constraints, or controlling bursts of async operations. ## Example ```tsx -// Basic API call rate limiting +// Basic API call rate limiting with return value const { maybeExecute } = createAsyncRateLimiter( async (id: string) => { const data = await api.fetchData(id); - return data; + return data; // Return value is preserved }, { limit: 5, window: 1000 } // 5 calls per second ); -// With state management +// With state management and return value const [data, setData] = createSignal(null); const { maybeExecute } = createAsyncRateLimiter( async (query) => { const result = await searchAPI(query); setData(result); + return result; // Return value can be used by the caller }, { limit: 10, diff --git a/docs/ja/framework/solid/reference/functions/createratelimitedsignal.md b/docs/ja/framework/solid/reference/functions/createratelimitedsignal.md index f966b8720..63a96e0ac 100644 --- a/docs/ja/framework/solid/reference/functions/createratelimitedsignal.md +++ b/docs/ja/framework/solid/reference/functions/createratelimitedsignal.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:06:43.650Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:47:46.083Z' id: createRateLimitedSignal title: createRateLimitedSignal --- @@ -13,7 +13,7 @@ title: createRateLimitedSignal function createRateLimitedSignal(value, initialOptions): [Accessor, Setter, SolidRateLimiter>] ``` -Defined in: [rate-limiter/createRateLimitedSignal.ts:57](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedSignal.ts#L57) +Defined in: [rate-limiter/createRateLimitedSignal.ts:65](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedSignal.ts#L65) A Solid hook that creates a rate-limited state value that enforces a hard limit on state updates within a time window. This hook combines Solid's createSignal with rate limiting functionality to provide controlled state updates. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - createThrottledSignal: When you want consistent spacing between updates (e.g. UI changes) - createDebouncedSignal: When you want to collapse rapid updates into a single update (e.g. search input) @@ -57,16 +63,18 @@ consider using the lower-level createRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update state at most 5 times per minute +// Basic rate limiting - update state at most 5 times per minute with a sliding window const [value, setValue, rateLimiter] = createRateLimitedSignal(0, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); -// With rejection callback +// With rejection callback and fixed window const [value, setValue] = createRateLimitedSignal(0, { limit: 3, window: 5000, + windowType: 'fixed', onReject: (rateLimiter) => { alert(`Rate limit reached. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/ja/framework/solid/reference/functions/createratelimitedvalue.md b/docs/ja/framework/solid/reference/functions/createratelimitedvalue.md index e88d6ded0..c1a75b815 100644 --- a/docs/ja/framework/solid/reference/functions/createratelimitedvalue.md +++ b/docs/ja/framework/solid/reference/functions/createratelimitedvalue.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:06:43.645Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:47:46.079Z' id: createRateLimitedValue title: createRateLimitedValue --- @@ -13,7 +13,7 @@ title: createRateLimitedValue function createRateLimitedValue(value, initialOptions): [Accessor, SolidRateLimiter>] ``` -Defined in: [rate-limiter/createRateLimitedValue.ts:43](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedValue.ts#L43) +Defined in: [rate-limiter/createRateLimitedValue.ts:50](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedValue.ts#L50) A high-level Solid hook that creates a rate-limited version of a value that updates at most a certain number of times within a time window. This hook uses Solid's createSignal internally to manage the rate-limited state. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - createThrottledValue: When you want consistent spacing between updates (e.g. UI changes) - createDebouncedValue: When you want to collapse rapid updates into a single update (e.g. search input) @@ -56,10 +62,11 @@ consider using the lower-level createRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update at most 5 times per minute +// Basic rate limiting - update at most 5 times per minute with a sliding window const [rateLimitedValue, rateLimiter] = createRateLimitedValue(rawValue, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); // Use the rate-limited value diff --git a/docs/ja/framework/solid/reference/functions/createratelimiter.md b/docs/ja/framework/solid/reference/functions/createratelimiter.md index c62817565..8075f41b1 100644 --- a/docs/ja/framework/solid/reference/functions/createratelimiter.md +++ b/docs/ja/framework/solid/reference/functions/createratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:06:43.642Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:47:46.076Z' id: createRateLimiter title: createRateLimiter --- @@ -13,7 +13,7 @@ title: createRateLimiter function createRateLimiter(fn, initialOptions): SolidRateLimiter ``` -Defined in: [rate-limiter/createRateLimiter.ts:61](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts#L61) +Defined in: [rate-limiter/createRateLimiter.ts:68](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts#L68) A low-level Solid hook that creates a `RateLimiter` instance to enforce rate limits on function execution. @@ -24,6 +24,12 @@ Rate limiting is a simple "hard limit" approach that allows executions until a m a time window, then blocks all subsequent calls until the window resets. Unlike throttling or debouncing, it does not attempt to space out or collapse executions intelligently. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns: - Use throttling when you want consistent spacing between executions (e.g. UI updates) - Use debouncing when you want to collapse rapid-fire events (e.g. search input) @@ -50,10 +56,11 @@ For smoother execution patterns: ## Example ```tsx -// Basic rate limiting - max 5 calls per minute +// Basic rate limiting - max 5 calls per minute with a sliding window const rateLimiter = createRateLimiter(apiCall, { limit: 5, window: 60000, + windowType: 'sliding' }); // Monitor rate limit status diff --git a/docs/ja/guides/debouncing.md b/docs/ja/guides/debouncing.md index 0dab616d4..e8ed19a1a 100644 --- a/docs/ja/guides/debouncing.md +++ b/docs/ja/guides/debouncing.md @@ -1,43 +1,41 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:09:25.958Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:50:36.107Z' title: デバウンスガイド id: debouncing --- -以下は翻訳されたドキュメントです。 - # デバウンスガイド -TanStack Pacerは、アプリケーション内での関数実行タイミングを制御するための高品質なユーティリティを提供するライブラリです。類似のユーティリティは他にも存在しますが、私たちは***タイプセーフ***、***ツリーシェイキング***、一貫性のある***直感的なAPI***など、重要な詳細をすべて正しく実装することを目指しています。これらの基本機能に焦点を当て、***フレームワークに依存しない***形で提供することで、これらのユーティリティとパターンがアプリケーションでより一般的に使用されることを願っています。適切な実行制御はアプリケーション開発において後回しにされがちで、パフォーマンス問題、競合状態、回避可能だったユーザー体験の低下を引き起こします。TanStack Pacerを使えば、これらの重要なパターンを最初から正しく実装できます! +TanStack Pacerは、アプリケーション内での関数実行タイミングを制御するための高品質なユーティリティを提供するライブラリです。類似のユーティリティは他にも存在しますが、私たちは***型安全性***、***ツリーシェイキング***、一貫性のある***直感的なAPI***など、重要な詳細をすべて正しく実装することを目指しています。これらの基本機能に焦点を当て、***フレームワークに依存しない***方法で提供することで、これらのユーティリティとパターンがアプリケーションでより一般的に使用されることを願っています。適切な実行制御はアプリケーション開発において後回しにされがちで、パフォーマンス問題、競合状態、回避可能だったユーザーエクスペリエンスの低下を引き起こします。TanStack Pacerは、これらの重要なパターンを最初から正しく実装するのに役立ちます! -レートリミット、スロットリング、デバウンスは、関数実行頻度を制御する3つの異なるアプローチです。各手法は実行を異なる方法でブロックし、「ロッシー」(損失あり)な特性を持ちます - つまり、関数呼び出しが頻繁に行われた場合、一部の呼び出しは実行されません。各アプローチを使用する適切なタイミングを理解することは、パフォーマンスが高く信頼性のあるアプリケーションを構築する上で重要です。このガイドでは、TanStack Pacerのデバウンス概念について説明します。 +レートリミット、スロットリング、デバウンスは、関数の実行頻度を制御する3つの異なるアプローチです。各手法は実行を異なる方法でブロックし、「ロッシー(損失あり)」になります - つまり、関数呼び出しが頻繁に行われすぎた場合、一部の呼び出しは実行されません。各アプローチをいつ使用するかを理解することは、パフォーマンスが高く信頼性のあるアプリケーションを構築するために重要です。このガイドでは、TanStack Pacerのデバウンス概念について説明します。 ## デバウンスの概念 -デバウンスは、指定された期間アクティビティが発生しなくなるまで関数の実行を遅延させる技術です。一定限度まで実行のバーストを許可するレートリミットや、均等な間隔で実行を保証するスロットリングとは異なり、デバウンスは複数の高速な関数呼び出しを、呼び出しが停止した後にのみ発生する単一の実行にまとめます。これにより、デバウンスはアクティビティが落ち着いた後の最終状態のみを気にするイベントのバースト処理に理想的です。 +デバウンスは、指定された期間の非アクティブ状態が発生するまで関数の実行を遅延させる技術です。制限まで実行のバーストを許可するレートリミットや、均等に間隔を空けた実行を保証するスロットリングとは異なり、デバウンスは複数の高速な関数呼び出しを、呼び出しが停止した後にのみ発生する単一の実行にまとめます。これにより、デバウンスはアクティビティが落ち着いた後の最終状態のみを気にするイベントのバースト処理に理想的です。 ### デバウンスの可視化 ```text -デバウンス(待機時間: 3ティック) -タイムライン: [1秒/ティック] -呼び出し: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ -実行: ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ⏳ -> ✅ ❌ ⏳ -> ✅ +Debouncing (wait: 3 ticks) +Timeline: [1 second per tick] +Calls: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ +Executed: ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ⏳ -> ✅ ❌ ⏳ -> ✅ [=================================================================] - ^ ここで実行 - 呼び出しが3ティックない後 + ^ 呼び出しが3ティック + ない後にここで実行 [呼び出しのバースト] [さらに呼び出し] [待機] [新しいバースト] 実行なし タイマーリセット [遅延実行] [待機] [遅延実行] ``` -### デバウンスを使用するタイミング +### デバウンスを使用すべき場合 -デバウンスは、アクションを実行する前に「一時停止」を待ちたい場合に特に効果的です。これは、最終状態のみを気にするユーザー入力やその他の高速発生イベントの処理に理想的です。 +デバウンスは、アクションを実行する前にアクティビティの「一時停止」を待ちたい場合に特に効果的です。これは、最終状態のみを気にするユーザー入力やその他の高速発火イベントの処理に理想的です。 -一般的な使用例: +一般的な使用例: - ユーザーが入力を終えるのを待ちたい検索入力フィールド -- キーストロークごとに実行すべきでないフォームバリデーション +- キーストロークごとに実行すべきではないフォームバリデーション - 計算コストが高いウィンドウリサイズ計算 - コンテンツ編集中の自動ドラフト保存 - ユーザーアクティビティが落ち着いた後にのみ発生すべきAPI呼び出し @@ -45,22 +43,22 @@ TanStack Pacerは、アプリケーション内での関数実行タイミング ### デバウンスを使用すべきでない場合 -デバウンスが最適でない場合: -- 特定期間での実行保証が必要な場合(代わりに[スロットリング](../guides/throttling)を使用) -- いかなる実行も見逃せない場合(代わりに[キューイング](../guides/queueing)を使用) +デバウンスが最適な選択でない場合: +- 特定の期間にわたって確実に実行する必要がある場合(代わりに[スロットリング](../guides/throttling)を使用) +- いかなる実行も見逃すことが許されない場合(代わりに[キューイング](../guides/queueing)を使用) ## TanStack Pacerでのデバウンス -TanStack Pacerは、`Debouncer`クラスと`AsyncDebouncer`クラス(および対応する`debounce`と`asyncDebounce`関数)を介して、同期および非同期のデバウンスを提供します。 +TanStack Pacerは、`Debouncer`と`AsyncDebouncer`クラス(および対応する`debounce`と`asyncDebounce`関数)を介して、同期および非同期のデバウンスを提供します。 ### `debounce`を使った基本的な使用法 -`debounce`関数は、任意の関数にデバウンスを追加する最も簡単な方法です: +`debounce`関数は、任意の関数にデバウンスを追加する最も簡単な方法です: ```ts import { debounce } from '@tanstack/pacer' -// ユーザーが入力を止めるのを待つ検索入力のデバウンス +// ユーザーが入力をやめるのを待つ検索入力のデバウンス const debouncedSearch = debounce( (searchTerm: string) => performSearch(searchTerm), { @@ -75,7 +73,7 @@ searchInput.addEventListener('input', (e) => { ### `Debouncer`クラスを使った高度な使用法 -デバウンス動作をより細かく制御するには、`Debouncer`クラスを直接使用できます: +デバウンス動作をより詳細に制御するには、`Debouncer`クラスを直接使用できます: ```ts import { Debouncer } from '@tanstack/pacer' @@ -90,7 +88,7 @@ console.log(searchDebouncer.getExecutionCount()) // 成功した実行回数 console.log(searchDebouncer.getIsPending()) // 呼び出しが保留中かどうか // オプションを動的に更新 -searchDebouncer.setOptions({ wait: 1000 }) // 待機時間を増加 +searchDebouncer.setOptions({ wait: 1000 }) // 待機時間を増やす // 保留中の実行をキャンセル searchDebouncer.cancel() @@ -98,7 +96,7 @@ searchDebouncer.cancel() ### 先頭と末尾の実行 -同期デバウンサーは先頭(leading)と末尾(trailing)の両方の実行をサポートします: +同期デバウンサーは、先頭エッジと末尾エッジの両方の実行をサポートします: ```ts const debouncedFn = debounce(fn, { @@ -111,53 +109,53 @@ const debouncedFn = debounce(fn, { - `leading: true` - 最初の呼び出しで即時実行 - `leading: false` (デフォルト) - 最初の呼び出しで待機タイマー開始 - `trailing: true` (デフォルト) - 待機期間後に実行 -- `trailing: false` - 待機期間後の実行なし +- `trailing: false` - 待機期間後に実行なし -一般的なパターン: +一般的なパターン: - `{ leading: false, trailing: true }` - デフォルト、待機後に実行 - `{ leading: true, trailing: false }` - 即時実行、後続の呼び出しを無視 - `{ leading: true, trailing: true }` - 最初の呼び出し時と待機後の両方で実行 ### 最大待機時間 -TanStack Pacerのデバウンサーは意図的に、他のデバウンスライブラリのような`maxWait`オプションを持っていません。実行をより分散させたい場合は、代わりに[スロットリング](../guides/throttling)技術の使用を検討してください。 +TanStack Pacerのデバウンサーは、他のデバウンスライブラリのような`maxWait`オプションを意図的に持っていません。実行をより分散させたい場合は、代わりに[スロットリング](../guides/throttling)技術の使用を検討してください。 -### 有効/無効化 +### 有効化/無効化 -`Debouncer`クラスは`enabled`オプションを介した有効/無効化をサポートします。`setOptions`メソッドを使用して、いつでもデバウンサーを有効/無効にできます: +`Debouncer`クラスは、`enabled`オプションを介して有効化/無効化をサポートします。`setOptions`メソッドを使用すると、いつでもデバウンサーを有効化/無効化できます: ```ts const debouncer = new Debouncer(fn, { wait: 500, enabled: false }) // デフォルトで無効 debouncer.setOptions({ enabled: true }) // いつでも有効化 ``` -デバウンサーオプションがリアクティブなフレームワークアダプターを使用している場合、`enabled`オプションに条件付きの値を設定して、デバウンサーを動的に有効/無効にできます: +デバウンサーオプションがリアクティブなフレームワークアダプターを使用している場合、`enabled`オプションを条件付きの値に設定して、デバウンサーを動的に有効化/無効化できます: ```ts // Reactの例 const debouncer = useDebouncer( setSearch, - { wait: 500, enabled: searchInput.value.length > 3 } // 入力長に基づいて有効/無効化(リアクティブオプションをサポートするフレームワークアダプターを使用している場合) + { wait: 500, enabled: searchInput.value.length > 3 } // 入力長に基づいて有効化/無効化(リアクティブオプションをサポートするフレームワークアダプターを使用している場合) ) ``` -ただし、`debounce`関数または`Debouncer`クラスを直接使用している場合、`enabled`オプションを変更するには`setOptions`メソッドを使用する必要があります。渡されるオプションは実際には`Debouncer`クラスのコンストラクターに渡されるためです。 +ただし、`debounce`関数または`Debouncer`クラスを直接使用している場合、`enabled`オプションを変更するには`setOptions`メソッドを使用する必要があります。渡されるオプションは実際には`Debouncer`クラスのコンストラクタに渡されるためです。 ```ts // Solidの例 const debouncer = new Debouncer(fn, { wait: 500, enabled: false }) // デフォルトで無効 createEffect(() => { - debouncer.setOptions({ enabled: search().length > 3 }) // 入力長に基づいて有効/無効化 + debouncer.setOptions({ enabled: search().length > 3 }) // 入力長に基づいて有効化/無効化 }) ``` ### コールバックオプション -同期および非同期のデバウンサーは、デバウンスライフサイクルのさまざまな側面を処理するためのコールバックオプションをサポートしています: +同期および非同期のデバウンサーは、デバウンスライフサイクルのさまざまな側面を処理するためのコールバックオプションをサポートしています: #### 同期デバウンサーのコールバック -同期`Debouncer`は以下のコールバックをサポートします: +同期`Debouncer`は次のコールバックをサポートします: ```ts const debouncer = new Debouncer(fn, { @@ -169,7 +167,7 @@ const debouncer = new Debouncer(fn, { }) ``` -`onExecute`コールバックは、デバウンスされた関数が正常に実行されるたびに呼び出され、実行の追跡、UI状態の更新、またはクリーンアップ操作の実行に役立ちます。 +`onExecute`コールバックは、デバウンスされた関数の各成功実行後に呼び出され、実行の追跡、UI状態の更新、またはクリーンアップ操作の実行に役立ちます。 #### 非同期デバウンサーのコールバック @@ -195,37 +193,31 @@ const asyncDebouncer = new AsyncDebouncer(async (value) => { }) ``` -`onSuccess`コールバックはデバウンスされた関数が正常に実行されるたびに呼び出され、`onError`コールバックは非同期関数がエラーをスローした場合に呼び出されます。`onSettled`コールバックは、成功または失敗に関係なく、各実行試行後に呼び出されます。これらのコールバックは、実行回数の追跡、UI状態の更新、エラー処理、クリーンアップ操作、および実行メトリクスのロギングに特に役立ちます。 +`onSuccess`コールバックはデバウンスされた関数の各成功実行後に呼び出され、`onError`コールバックは非同期関数がエラーをスローした場合に呼び出されます。`onSettled`コールバックは、成功または失敗に関係なく、各実行試行後に呼び出されます。これらのコールバックは、実行回数の追跡、UI状態の更新、エラー処理、クリーンアップ操作、および実行メトリクスのロギングに特に役立ちます。 ### 非同期デバウンス -非同期デバウンサーは、非同期操作をデバウンスで処理する強力な方法を提供し、同期バージョンに比べていくつかの重要な利点があります。同期デバウンサーがUIイベントと即時フィードバックに適しているのに対し、非同期バージョンはAPI呼び出し、データベース操作、およびその他の非同期タスクの処理に特化して設計されています。 +非同期デバウンサーは、非同期操作をデバウンスで処理する強力な方法を提供し、同期バージョンに比べていくつかの重要な利点があります。同期デバウンサーがUIイベントと即時のフィードバックに適しているのに対し、非同期バージョンはAPI呼び出し、データベース操作、およびその他の非同期タスクの処理に特化して設計されています。 #### 同期デバウンスとの主な違い 1. **戻り値の処理** -同期デバウンサーがvoidを返すのとは異なり、非同期バージョンではデバウンスされた関数からの戻り値をキャプチャして使用できます。これはAPI呼び出しやその他の非同期操作の結果を扱う必要がある場合に特に便利です。`maybeExecute`メソッドは関数の戻り値で解決するPromiseを返し、結果を適切に処理できます。 - -2. **強化されたコールバックシステム** -非同期デバウンサーは、同期バージョンの単一の`onExecute`コールバックに比べて、より洗練されたコールバックシステムを提供します。このシステムには以下が含まれます: -- `onSuccess`: 非同期関数が正常に完了したときに呼び出され、結果とデバウンサーインスタンスの両方を提供 -- `onError`: 非同期関数がエラーをスローしたときに呼び出され、エラーとデバウンサーインスタンスの両方を提供 -- `onSettled`: 成功または失敗に関係なく、すべての実行試行後に呼び出される +同期デバウンサーがvoidを返すのとは異なり、非同期バージョンではデバウンスされた関数からの戻り値をキャプチャして使用できます。これはAPI呼び出しやその他の非同期操作の結果を操作する必要がある場合に特に便利です。`maybeExecute`メソッドは、関数の戻り値で解決されるPromiseを返し、結果を待機して適切に処理できるようにします。 -3. **実行追跡** -非同期デバウンサーは、いくつかのメソッドを通じて包括的な実行追跡を提供します: -- `getSuccessCount()`: 成功した実行回数 -- `getErrorCount()`: 失敗した実行回数 -- `getSettledCount()`: 完了した実行の総数(成功 + 失敗) +2. **異なるコールバック** +`AsyncDebouncer`は、同期バージョンの`onExecute`だけでなく、次のコールバックをサポートします: +- `onSuccess`: 各成功実行後に呼び出され、デバウンサーインスタンスを提供 +- `onSettled`: 各実行後に呼び出され、デバウンサーインスタンスを提供 +- `onError`: 非同期関数がエラーをスローした場合に呼び出され、エラーとデバウンサーインスタンスの両方を提供 -4. **順次実行** -非同期デバウンサーは、後続の実行が前の呼び出しの完了を待つことを保証します。これにより、順不同の実行が防止され、各呼び出しが最新のデータを処理することが保証されます。これは、前の呼び出しの結果に依存する操作や、データの一貫性を維持することが重要な場合に特に重要です。 +3. **順次実行** +デバウンサーの`maybeExecute`メソッドはPromiseを返すため、次の実行を開始する前に各実行を待機することを選択できます。これにより、実行順序を制御し、各呼び出しが最新のデータを処理することを保証できます。これは、以前の呼び出しの結果に依存する操作や、データの一貫性を維持することが重要な場合に特に役立ちます。 -例えば、ユーザーのプロファイルを更新し、すぐに更新されたデータを取得する場合、非同期デバウンサーは取得操作が更新の完了を待つようにし、古いデータを取得する可能性のある競合状態を防ぎます。 +たとえば、ユーザーのプロファイルを更新してからすぐに更新されたデータを取得する場合、取得操作を開始する前に更新操作を待機できます: #### 基本的な使用例 -以下は、検索操作に非同期デバウンサーを使用する基本的な例です: +検索操作に非同期デバウンサーを使用する基本的な例を次に示します: ```ts const debouncedSearch = asyncDebounce( @@ -248,24 +240,11 @@ const debouncedSearch = asyncDebounce( const results = await debouncedSearch('query') ``` -#### 高度なパターン - -非同期デバウンサーは、複雑な問題を解決するためにさまざまなパターンと組み合わせることができます: - -1. **状態管理との統合** -非同期デバウンサーを状態管理システム(ReactのuseStateやSolidのcreateSignalなど)と使用する場合、ローディング状態、エラー状態、およびデータ更新を処理するための強力なパターンを作成できます。デバウンサーのコールバックは、操作の成功または失敗に基づいてUI状態を更新するための完璧なフックを提供します。 - -2. **競合状態の防止** -シングルフライトミューテーションパターンは、多くのシナリオで自然に競合状態を防ぎます。アプリケーションの複数の部分が同時に同じリソースを更新しようとした場合、デバウンサーは最新の更新のみが実際に発生するようにしつつ、すべての呼び出し元に結果を提供します。 - -3. **エラー回復** -非同期デバウンサーのエラー処理機能は、リトロジックやエラー回復パターンの実装に理想的です。`onError`コールバックを使用して、指数バックオフやフォールバックメカニズムなどのカスタムエラー処理戦略を実装できます。 - ### フレームワークアダプター -各フレームワークアダプターは、コアのデバウンス機能を基に構築され、フレームワークの状態管理システムと統合するためのフックを提供します。`createDebouncer`、`useDebouncedCallback`、`useDebouncedState`、または`useDebouncedValue`などのフックが各フレームワークで利用可能です。 +各フレームワークアダプターは、コアのデバウンス機能を基に構築され、フレームワークの状態管理システムと統合するためのフックを提供します。`createDebouncer`、`useDebouncedCallback`、`useDebouncedState`、`useDebouncedValue`などのフックが各フレームワークで利用可能です。 -以下にいくつかの例を示します: +いくつかの例: #### React @@ -295,4 +274,19 @@ const [debouncedValue] = useDebouncedValue( #### Solid ```tsx -import { createDebouncer, createDebouncedSignal } from '@tanstack/solid-p +import { createDebouncer, createDebouncedSignal } from '@tanstack/solid-pacer' + +// 完全な制御のための低レベルフック +const debouncer = createDebouncer( + (value: string) => saveToDatabase(value), + { wait: 500 } +) + +// 状態管理のためのシグナルベースのフック +const [searchTerm, setSearchTerm, debouncer] = createDebouncedSignal('', { + wait: 500, + onExecute: (debouncer) => { + console.log('総実行回数:', debouncer.getExecutionCount()) + } +}) +``` diff --git a/docs/ja/guides/rate-limiting.md b/docs/ja/guides/rate-limiting.md index 04c3c8888..0da64f1d3 100644 --- a/docs/ja/guides/rate-limiting.md +++ b/docs/ja/guides/rate-limiting.md @@ -1,19 +1,19 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:09:26.534Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:50:45.049Z' title: レート制限ガイド id: rate-limiting --- # レートリミティングガイド -レートリミティング(Rate Limiting)、スロットリング(Throttling)、デバウンス(Debouncing)は、関数の実行頻度を制御する3つの異なるアプローチです。各手法は実行を異なる方法でブロックし、「ロッシー(lossy)」な性質を持ちます - つまり、関数が頻繁に呼び出されるとき、一部の関数呼び出しは実行されません。パフォーマンスが高く信頼性のあるアプリケーションを構築するためには、各アプローチを使用するタイミングを理解することが重要です。このガイドでは、TanStack Pacerのレートリミティング概念について説明します。 +レートリミティング (Rate Limiting)、スロットリング (Throttling)、デバウンス (Debouncing) は、関数の実行頻度を制御する3つの異なるアプローチです。各手法は実行を異なる方法でブロックするため、「ロッシー (lossy)」、つまり関数呼び出しが頻繁に要求されると一部の実行が行われない可能性があります。パフォーマンスが高く信頼性のあるアプリケーションを構築するためには、各アプローチを使用するタイミングを理解することが重要です。このガイドでは、TanStack Pacerのレートリミティング概念について説明します。 > [!NOTE] > TanStack Pacerは現在フロントエンドライブラリのみです。これらはクライアントサイドのレートリミティング用ユーティリティです。 ## レートリミティングの概念 -レートリミティングは、特定の時間枠内で関数が実行できる回数を制限する技術です。APIリクエストや他の外部サービス呼び出しを処理する際など、関数が過剰に呼び出されるのを防ぎたいシナリオで特に有用です。これは最も*単純な*アプローチであり、クォータが満たされるまで実行がバースト的に発生することを許容します。 +レートリミティングは、特定の時間枠内で関数が実行できる回数を制限する技術です。APIリクエストや他の外部サービス呼び出しを処理する際など、関数が頻繁に呼び出されるのを防ぎたいシナリオで特に有用です。これは最も*単純な*アプローチであり、クォータが満たされるまで実行がバースト的に発生することを許容します。 ### レートリミティングの可視化 @@ -21,36 +21,65 @@ id: rate-limiting Rate Limiting (limit: 3 calls per window) Timeline: [1 second per tick] Window 1 | Window 2 -Calls: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ �️ +Calls: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ Executed: ✅ ✅ ✅ ❌ ❌ ✅ ✅ [=== 3 allowed ===][=== blocked until window ends ===][=== new window =======] ``` +### ウィンドウタイプ + +TanStack Pacerは2種類のレートリミティングウィンドウをサポートしています: + +1. **固定ウィンドウ (Fixed Window)** (デフォルト) + - ウィンドウ期間後にリセットされる厳密なウィンドウ + - ウィンドウ内のすべての実行が制限にカウントされる + - 期間後にウィンドウが完全にリセットされる + - ウィンドウ境界でバースト的な動作が発生する可能性がある + +2. **スライディングウィンドウ (Sliding Window)** + - 古い実行が期限切れになると新しい実行を許可するローリングウィンドウ + - 時間経過に伴ってより一貫した実行レートを提供 + - 実行の安定したフローを維持するのに適している + - ウィンドウ境界でのバースト的な動作を防ぐ + +スライディングウィンドウレートリミティングの可視化: + +```text +Sliding Window Rate Limiting (limit: 3 calls per window) +Timeline: [1 second per tick] + Window 1 | Window 2 +Calls: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ +Executed: ✅ ✅ ✅ ❌ ✅ ✅ ✅ + [=== 3 allowed ===][=== oldest expires, new allowed ===][=== continues sliding =======] +``` + +重要な違いは、スライディングウィンドウでは最も古い実行が期限切れになるとすぐに新しい実行が許可されることです。これにより、固定ウィンドウアプローチと比較してより一貫した実行フローが作成されます。 + ### レートリミティングを使用するタイミング レートリミティングは、バックエンドサービスに過剰な負荷をかけたり、ブラウザでパフォーマンス問題を引き起こす可能性のあるフロントエンド操作を扱う際に特に重要です。 一般的な使用例: -- ユーザーの迅速な操作(ボタンクリックやフォーム送信など)による意図しないAPIスパムの防止 -- バースト的な動作が許容されるが、最大レートを制限したいシナリオ -- 意図しない無限ループや再帰操作からの保護 +- ユーザーの迅速な操作(ボタンクリックやフォーム送信など)による誤ったAPIスパムの防止 +- バースト的な動作が許容可能だが最大レートを制限したいシナリオ +- 誤った無限ループや再帰操作からの保護 ### レートリミティングを使用しないタイミング -レートリミティングは、関数実行頻度を制御する最も単純なアプローチです。3つの手法の中で最も柔軟性が低く、制限的です。より間隔を空けた実行が必要な場合は、[スロットリング](../guides/throttling)または[デバウンス](../guides/debouncing)の使用を検討してください。 +レートリミティングは、関数実行頻度を制御する最も単純なアプローチです。3つの手法の中で最も柔軟性が低く、制限的です。より間隔を空けた実行が必要な場合は、代わりに[スロットリング](../guides/throttling)または[デバウンス](../guides/debouncing)の使用を検討してください。 > [!TIP] -> ほとんどのユースケースでは「レートリミティング」を使用したくないでしょう。[スロットリング](../guides/throttling)または[デバウンス](../guides/debouncing)の使用を検討してください。 +> ほとんどのユースケースでは「レートリミティング」を使用したくないでしょう。代わりに[スロットリング](../guides/throttling)または[デバウンス](../guides/debouncing)の使用を検討してください。 -レートリミティングの「ロッシー(lossy)」な性質は、一部の実行が拒否され失われることを意味します。すべての実行が常に成功することを保証する必要がある場合、これは問題になる可能性があります。実行レートを遅くするためにスロットルされた遅延で実行されるようにすべての実行をキューイングする必要がある場合は、[キューイング](../guides/queueing)の使用を検討してください。 +レートリミティングの「ロッシー (lossy)」な性質は、一部の実行が拒否され失われることを意味します。すべての実行が常に成功することを保証する必要がある場合、これは問題になる可能性があります。実行レートを遅くするためにスロットルされた遅延で実行されるようにすべての実行をキューに入れる必要がある場合は、[キューイング](../guides/queueing)の使用を検討してください。 ## TanStack Pacerでのレートリミティング -TanStack Pacerは、`RateLimiter`クラスと`AsyncRateLimiter`クラス(および対応する`rateLimit`と`asyncRateLimit`関数)を介して、同期型と非同期型のレートリミティングを提供します。 +TanStack Pacerは、`RateLimiter`クラスと`AsyncRateLimiter`クラス(および対応する`rateLimit`と`asyncRateLimit`関数)を介して、同期および非同期のレートリミティングを提供します。 -### `rateLimit`での基本的な使用法 +### `rateLimit`を使用した基本的な使用法 -`rateLimit`関数は、任意の関数にレートリミティングを追加する最も簡単な方法です。単純な制限を強制するだけでよいほとんどのユースケースに最適です。 +`rateLimit`関数は、任意の関数にレートリミティングを追加する最も簡単な方法です。単純な制限を適用する必要があるほとんどのユースケースに最適です。 ```ts import { rateLimit } from '@tanstack/pacer' @@ -61,6 +90,7 @@ const rateLimitedApi = rateLimit( { limit: 5, window: 60 * 1000, // 1分(ミリ秒) + windowType: 'fixed', // デフォルト onReject: (rateLimiter) => { console.log(`レート制限を超えました。${rateLimiter.getMsUntilNextWindow()}ms後に再試行してください`) } @@ -76,9 +106,9 @@ rateLimitedApi('user-5') // ✅ 実行 rateLimitedApi('user-6') // ❌ ウィンドウがリセットされるまで拒否 ``` -### `RateLimiter`クラスでの高度な使用法 +### `RateLimiter`クラスを使用した高度な使用法 -レートリミティングの動作をさらに制御する必要があるより複雑なシナリオでは、`RateLimiter`クラスを直接使用できます。これにより、追加のメソッドや状態情報にアクセスできます。 +レートリミティングの動作を追加で制御する必要があるより複雑なシナリオでは、`RateLimiter`クラスを直接使用できます。これにより、追加のメソッドや状態情報にアクセスできます。 ```ts import { RateLimiter } from '@tanstack/pacer' @@ -107,7 +137,7 @@ console.log(limiter.getRejectionCount()) // 拒否された実行の総数 limiter.maybeExecute('user-1') // オプションを動的に更新 -limiter.setOptions({ limit: 10 }) // 制限を増加 +limiter.setOptions({ limit: 10 }) // 制限を増やす // すべてのカウンターと状態をリセット limiter.reset() @@ -115,7 +145,10 @@ limiter.reset() ### 有効化/無効化 -`RateLimiter`クラスは、`enabled`オプションを介して有効化/無効化をサポートしています。`setOptions`メソッドを使用して、いつでもレートリミッターを有効化/無効化できます: +`RateLimiter`クラスは、`enabled`オプションを介して有効化/無効化をサポートしています。`setOptions`メソッドを使用すると、いつでもレートリミッターを有効化/無効化できます: + +> [!NOTE] +> `enabled`オプションは実際の関数実行を有効化/無効化します。レートリミッターを無効にしてもレートリミティングはオフになりませんが、関数がまったく実行されなくなります。 ```ts const limiter = new RateLimiter(fn, { @@ -126,15 +159,15 @@ const limiter = new RateLimiter(fn, { limiter.setOptions({ enabled: true }) // いつでも有効化 ``` -レートリミッターオプションがリアクティブなフレームワークアダプターを使用している場合、`enabled`オプションを条件付きの値に設定して、レートリミッターを動的に有効化/無効化できます。ただし、`rateLimit`関数または`RateLimiter`クラスを直接使用している場合、`enabled`オプションを変更するには`setOptions`メソッドを使用する必要があります。渡されるオプションは実際には`RateLimiter`クラスのコンストラクターに渡されるためです。 +レートリミッターオプションがリアクティブなフレームワークアダプターを使用している場合、`enabled`オプションを条件付きの値に設定して、レートリミッターを動的に有効化/無効化できます。ただし、`rateLimit`関数または`RateLimiter`クラスを直接使用している場合は、`enabled`オプションを変更するために`setOptions`メソッドを使用する必要があります。渡されるオプションは実際には`RateLimiter`クラスのコンストラクターに渡されるためです。 ### コールバックオプション -同期型と非同期型の両方のレートリミッターは、レートリミティングライフサイクルのさまざまな側面を処理するためのコールバックオプションをサポートしています: +同期および非同期のレートリミッターは、レートリミティングライフサイクルのさまざまな側面を処理するためのコールバックオプションをサポートしています: -#### 同期型レートリミッターのコールバック +#### 同期レートリミッターのコールバック -同期型`RateLimiter`は以下のコールバックをサポートします: +同期`RateLimiter`は次のコールバックをサポートします: ```ts const limiter = new RateLimiter(fn, { @@ -151,11 +184,11 @@ const limiter = new RateLimiter(fn, { }) ``` -`onExecute`コールバックは、レート制限された関数が正常に実行されるたびに呼び出され、`onReject`コールバックは、レートリミティングにより実行が拒否されたときに呼び出されます。これらのコールバックは、実行の追跡、UI状態の更新、またはユーザーへのフィードバックの提供に役立ちます。 +`onExecute`コールバックは、レート制限された関数の各成功した実行後に呼び出され、`onReject`コールバックは、レートリミティングにより実行が拒否されたときに呼び出されます。これらのコールバックは、実行の追跡、UI状態の更新、またはユーザーへのフィードバックの提供に役立ちます。 -#### 非同期型レートリミッターのコールバック +#### 非同期レートリミッターのコールバック -非同期型`AsyncRateLimiter`は、エラー処理のための追加コールバックをサポートします: +非同期`AsyncRateLimiter`は、エラー処理のための追加のコールバックをサポートします: ```ts const asyncLimiter = new AsyncRateLimiter(async (id) => { @@ -168,7 +201,7 @@ const asyncLimiter = new AsyncRateLimiter(async (id) => { console.log('非同期関数が実行されました', rateLimiter.getExecutionCount()) }, onReject: (rateLimiter) => { - // 実行がレートリミティングにより拒否されたときに呼び出される + // 実行が拒否されたときに呼び出される console.log(`レート制限を超えました。${rateLimiter.getMsUntilNextWindow()}ms後に再試行してください`) }, onError: (error) => { @@ -178,38 +211,33 @@ const asyncLimiter = new AsyncRateLimiter(async (id) => { }) ``` -`onExecute`および`onReject`コールバックは同期型レートリミッターと同じように機能し、`onError`コールバックは、レートリミティングチェーンを壊すことなくエラーを適切に処理できます。これらのコールバックは、実行回数の追跡、UI状態の更新、エラー処理、およびユーザーへのフィードバックの提供に特に役立ちます。 +`onExecute`および`onReject`コールバックは同期レートリミッターと同じように機能し、`onError`コールバックにより、レートリミティングチェーンを壊すことなくエラーを適切に処理できます。これらのコールバックは、実行回数の追跡、UI状態の更新、エラー処理、およびユーザーへのフィードバックの提供に特に役立ちます。 ### 非同期レートリミティング -非同期レートリミッターは、レートリミティングを使用して非同期操作を処理する強力な方法を提供し、同期バージョンに比べていくつかの重要な利点があります。同期レートリミッターがUIイベントと即時のフィードバックに適しているのに対し、非同期バージョンはAPI呼び出し、データベース操作、およびその他の非同期タスクの処理に特化して設計されています。 +非同期レートリミッターは、非同期操作をレートリミティングで処理する強力な方法を提供し、同期バージョンに比べていくつかの重要な利点があります。同期レートリミッターがUIイベントと即時のフィードバックに適しているのに対し、非同期バージョンは特にAPI呼び出し、データベース操作、およびその他の非同期タスクの処理用に設計されています。 -#### 同期型レートリミティングとの主な違い +#### 同期レートリミティングとの主な違い 1. **戻り値の処理** -同期型レートリミッターが成功を示すブール値を返すのとは異なり、非同期バージョンではレート制限された関数からの戻り値をキャプチャして使用できます。これは、API呼び出しやその他の非同期操作の結果を操作する必要がある場合に特に便利です。`maybeExecute`メソッドは、関数の戻り値で解決されるPromiseを返し、結果を適切に処理できるようにします。 +成功を示すブール値を返す同期レートリミッターとは異なり、非同期バージョンではレート制限された関数からの戻り値をキャプチャして使用できます。これは、API呼び出しやその他の非同期操作の結果を操作する必要がある場合に特に便利です。`maybeExecute`メソッドは、関数の戻り値で解決されるPromiseを返すため、結果を待機して適切に処理できます。 -2. **強化されたコールバックシステム** -非同期レートリミッターは、同期バージョンのコールバックに比べてより洗練されたコールバックシステムを提供します。このシステムには以下が含まれます: -- `onExecute`: 各成功した実行後に呼び出され、レートリミッターインスタンスを提供 -- `onReject`: レートリミティングにより実行が拒否されたときに呼び出され、レートリミッターインスタンスを提供 +2. **異なるコールバック** +`AsyncRateLimiter`は、同期バージョンの`onExecute`だけでなく、次のコールバックをサポートします: +- `onSuccess`: 各成功した実行後に呼び出され、レートリミッターインスタンスを提供 +- `onSettled`: 各実行後に呼び出され、レートリミッターインスタンスを提供 - `onError`: 非同期関数がエラーをスローした場合に呼び出され、エラーとレートリミッターインスタンスの両方を提供 -3. **実行追跡** -非同期レートリミッターは、いくつかのメソッドを通じて包括的な実行追跡を提供します: -- `getExecutionCount()`: 成功した実行の数 -- `getRejectionCount()`: 拒否された実行の数 -- `getRemainingInWindow()`: 現在のウィンドウ内の残り実行回数 -- `getMsUntilNextWindow()`: 次のウィンドウが開始するまでのミリ秒数 +非同期および同期レートリミッターの両方が、ブロックされた実行を処理するための`onReject`コールバックをサポートしています。 -4. **順次実行** -非同期レートリミッターは、後続の実行が前の呼び出しが完了するのを待ってから開始することを保証します。これにより、順不同の実行が防止され、各呼び出しが最新のデータを処理することが保証されます。これは、前の呼び出しの結果に依存する操作や、データの一貫性を維持することが重要な場合に特に重要です。 +3. **順次実行** +レートリミッターの`maybeExecute`メソッドはPromiseを返すため、各実行を待機してから次の実行を開始することを選択できます。これにより、実行順序を制御し、各呼び出しが最新のデータを処理することを保証できます。これは、前の呼び出しの結果に依存する操作や、データの一貫性を維持することが重要な場合に特に役立ちます。 -たとえば、ユーザーのプロファイルを更新してからすぐに更新されたデータを取得する場合、非同期レートリミッターは、更新が完了するまで取得操作が待機することを保証し、古いデータを取得する可能性のある競合状態を防止します。 +たとえば、ユーザーのプロファイルを更新してからすぐに更新されたデータを取得する場合、取得操作を開始する前に更新操作を待機できます: #### 基本的な使用例 -API操作に非同期レートリミッターを使用する基本的な例を以下に示します: +API操作に非同期レートリミッターを使用する方法を示す基本的な例: ```ts const rateLimitedApi = asyncRateLimit( @@ -236,24 +264,11 @@ const rateLimitedApi = asyncRateLimit( const result = await rateLimitedApi('123') ``` -#### 高度なパターン - -非同期レートリミッターは、さまざまなパターンと組み合わせて複雑な問題を解決できます: - -1. **状態管理との統合** -非同期レートリミッターを状態管理システム(ReactのuseStateやSolidのcreateSignalなど)と組み合わせて使用すると、ローディング状態、エラー状態、およびデータ更新を処理する強力なパターンを作成できます。レートリミッターのコールバックは、操作の成功または失敗に基づいてUI状態を更新するための完璧なフックを提供します。 - -2. **競合状態の防止** -レートリミティングパターンは、多くのシナリオで自然に競合状態を防止します。アプリケーションの複数の部分が同時に同じリソースを更新しようとする場合、レートリミッターは更新が構成された制限内で発生することを保証しながら、すべての呼び出し元に結果を提供します。 - -3. **エラー回復** -非同期レートリミッターのエラー処理機能は、再試行ロジックとエラー回復パターンを実装するのに理想的です。`onError`コールバックを使用して、指数バックオフやフォールバックメカニズムなどのカスタムエラー処理戦略を実装できます。 - ### フレームワークアダプター -各フレームワークアダプターは、コアのレートリミティング機能を基に構築され、フレームワークの状態管理システムと統合するためのフックを提供します。`createRateLimiter`、`useRateLimitedCallback`、`useRateLimitedState`、`useRateLimitedValue`などのフックが各フレームワークで利用可能です。 +各フレームワークアダプターは、フレームワークの状態管理システムと統合するために、コアのレートリミティング機能の上に構築されたフックを提供します。`createRateLimiter`、`useRateLimitedCallback`、`useRateLimitedState`、または`useRateLimitedValue`などのフックが各フレームワークで利用可能です。 -以下にいくつかの例を示します: +いくつかの例を示します: #### React @@ -272,7 +287,7 @@ const handleFetch = useRateLimitedCallback( { limit: 5, window: 1000 } ) -// リアクティブな状態管理のための状態ベースのフック +// リアクティブな状態管理のためのステートベースのフック const [instantState, setInstantState] = useState('') const [rateLimitedValue] = useRateLimitedValue( instantState, // レート制限する値 @@ -286,6 +301,4 @@ const [rateLimitedValue] = useRateLimitedValue( import { createRateLimiter, createRateLimitedSignal } from '@tanstack/solid-pacer' // 完全な制御のための低レベルフック -const limiter = createRateLimiter( - (id: string) => fetchUserData(id), - { +const limiter = createRateLim diff --git a/docs/ja/guides/throttling.md b/docs/ja/guides/throttling.md index 20af251d9..ee73cc1c7 100644 --- a/docs/ja/guides/throttling.md +++ b/docs/ja/guides/throttling.md @@ -1,57 +1,57 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:09:14.283Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:50:16.098Z' title: スロットリングガイド id: throttling --- # スロットリングガイド -レートリミット、スロットリング、デバウンスは、関数の実行頻度を制御する3つの異なるアプローチです。各手法は実行を異なる方法でブロックし、「ロスあり(lossy)」の動作となります。つまり、関数呼び出しが頻繁すぎる場合、一部の呼び出しは実行されません。パフォーマンスが高く信頼性のあるアプリケーションを構築するには、各アプローチを使い分けることが重要です。このガイドでは、TanStack Pacerのスロットリング概念について説明します。 +レートリミット (Rate Limiting)、スロットリング (Throttling)、デバウンス (Debouncing) は、関数の実行頻度を制御する3つの異なるアプローチです。各手法は実行を異なる方法でブロックし、「ロスあり (lossy)」の動作となります - つまり、関数呼び出しが頻繁に行われすぎると、一部の呼び出しが実行されません。パフォーマンスが高く信頼性のあるアプリケーションを構築するには、各アプローチを使用するタイミングを理解することが重要です。このガイドでは、TanStack Pacerのスロットリング概念について説明します。 ## スロットリングの概念 -スロットリングは、関数の実行を時間的に均等に分散させます。レートリミットが一定数までのバースト実行を許可したり、デバウンスがアクティビティが停止するのを待つのとは異なり、スロットリングは呼び出し間に一定の遅延を強制することで、よりスムーズな実行パターンを作成します。1秒に1回のスロットリングを設定した場合、呼び出しがどれだけ急速に要求されても、均等に間隔が空けられます。 +スロットリングは、関数の実行が時間的に均等に間隔を空けて行われることを保証します。制限までバースト実行を許可するレートリミットや、アクティビティが停止するのを待つデバウンスとは異なり、スロットリングは呼び出し間に一貫した遅延を強制することで、よりスムーズな実行パターンを作成します。1秒に1回のスロットリングを設定した場合、呼び出しがどれだけ急速に要求されても、均等に間隔が空けられます。 ### スロットリングの可視化 ```text -スロットリング(3ティックごとに1回実行) -タイムライン: [1ティックあたり1秒] -呼び出し: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ -実行: ✅ ❌ ⏳ -> ✅ ❌ ❌ ❌ ✅ ✅ +スロットリング (3ティックに1回実行) +タイムライン: [1ティック=1秒] +呼び出し: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ +実行: ✅ ❌ ⏳ -> ✅ ❌ ❌ ❌ ✅ ✅ [=================================================================] ^ 3ティックごとに1回のみ実行許可、 呼び出し回数に関係なく - [最初のバースト] [追加呼び出し] [間隔を空けた呼び出し] - 最初に実行し 待機期間後に実行 待機期間が経過するごとに実行 - その後スロットリング + [最初のバースト] [追加呼び出し] [間隔を空けた呼び出し] + 最初に実行後 待機期間後に実行 待機期間が経過するたびに実行 + スロットリング ``` -### スロットリングを使用する場面 +### スロットリングを使用するタイミング -スロットリングは、一貫性があり予測可能な実行タイミングが必要な場合に特に効果的です。これにより、スムーズで制御された動作が求められる頻繁なイベントや更新の処理に最適です。 +スロットリングは、一貫性があり予測可能な実行タイミングが必要な場合に特に効果的です。これにより、スムーズで制御された動作が必要な頻繁なイベントや更新の処理に最適です。 一般的な使用例: -- 一定のタイミングが必要なUI更新(例: プログレスインジケーター) -- ブラウザに過負荷をかけないスクロールやリサイズイベントハンドラー +- 一貫したタイミングが必要なUI更新(例: プログレスインジケーター) +- ブラウザに過負荷をかけないようにするスクロールやリサイズイベントハンドラ - 一定間隔が望ましいリアルタイムデータポーリング - 安定したペースが必要なリソース集約型操作 - ゲームループの更新やアニメーションフレーム処理 -- ユーザー入力時のライブ検索候補表示 +- ユーザーが入力する際のライブ検索候補表示 -### スロットリングを使用しない場面 +### スロットリングを使用しない方が良い場合 -以下の場合、スロットリングは最適な選択ではないかもしれません: +以下の場合はスロットリングが最適な選択ではないかもしれません: - アクティビティが停止するのを待ちたい場合(代わりに[デバウンス](../guides/debouncing)を使用) -- どの実行も見逃せない場合(代わりに[キューイング](../guides/queueing)を使用) +- いかなる実行も見逃したくない場合(代わりに[キューイング](../guides/queueing)を使用) > [!TIP] -> スロットリングは、スムーズで一貫した実行タイミングが必要な場合に最適な選択肢となることが多いです。レートリミットよりも予測可能な実行パターンを提供し、デバウンスよりも即時のフィードバックを提供します。 +> スロットリングは、スムーズで一貫した実行タイミングが必要な場合に最適な選択となることが多いです。レートリミットよりも予測可能な実行パターンを提供し、デバウンスよりも即時のフィードバックを提供します。 ## TanStack Pacerでのスロットリング -TanStack Pacerは、`Throttler`クラスと`AsyncThrottler`クラス(および対応する`throttle`と`asyncThrottle`関数)を通じて、同期型と非同期型の両方のスロットリングを提供します。 +TanStack Pacerは、`Throttler`クラスと`AsyncThrottler`クラス(および対応する`throttle`と`asyncThrottle`関数)を通じて、同期型と非同期型のスロットリングを提供します。 ### `throttle`を使った基本的な使用法 @@ -60,7 +60,7 @@ TanStack Pacerは、`Throttler`クラスと`AsyncThrottler`クラス(および ```ts import { throttle } from '@tanstack/pacer' -// UI更新を200msごとにスロットリング +// UI更新を200msに1回にスロットリング const throttledUpdate = throttle( (value: number) => updateProgressBar(value), { @@ -68,7 +68,7 @@ const throttledUpdate = throttle( } ) -// 高速ループ内では、200msごとにのみ実行 +// 高速ループでも200msごとにのみ実行 for (let i = 0; i < 100; i++) { throttledUpdate(i) // 多くの呼び出しがスロットリングされる } @@ -76,7 +76,7 @@ for (let i = 0; i < 100; i++) { ### `Throttler`クラスを使った高度な使用法 -スロットリング動作をより詳細に制御するには、`Throttler`クラスを直接使用できます: +スロットリング動作をより細かく制御するには、`Throttler`クラスを直接使用できます: ```ts import { Throttler } from '@tanstack/pacer' @@ -88,7 +88,7 @@ const updateThrottler = new Throttler( // 実行状態に関する情報を取得 console.log(updateThrottler.getExecutionCount()) // 成功した実行回数 -console.log(updateThrottler.getLastExecutionTime()) // 最後の実行タイムスタンプ +console.log(updateThrottler.getLastExecutionTime()) // 最後の実行のタイムスタンプ // 保留中の実行をキャンセル updateThrottler.cancel() @@ -96,12 +96,12 @@ updateThrottler.cancel() ### 先頭と末尾の実行 -同期型スロッターは、先頭(leading)と末尾(trailing)の両方のエッジ実行をサポートします: +同期スロッターは先頭(leading)と末尾(trailing)の両方の実行をサポートします: ```ts const throttledFn = throttle(fn, { wait: 200, - leading: true, // 最初の呼び出しで実行(デフォルト) + leading: true, // 最初の呼び出しで即時実行(デフォルト) trailing: true, // 待機期間後に実行(デフォルト) }) ``` @@ -109,31 +109,31 @@ const throttledFn = throttle(fn, { - `leading: true` (デフォルト) - 最初の呼び出しで即時実行 - `leading: false` - 最初の呼び出しをスキップし、末尾の実行を待つ - `trailing: true` (デフォルト) - 待機期間後に最後の呼び出しを実行 -- `trailing: false` - 待機期間内であれば最後の呼び出しをスキップ +- `trailing: false` - 待機期間内の場合、最後の呼び出しをスキップ 一般的なパターン: -- `{ leading: true, trailing: true }` - デフォルト、最も反応が速い +- `{ leading: true, trailing: true }` - デフォルト、最も反応が良い - `{ leading: false, trailing: true }` - すべての実行を遅延 - `{ leading: true, trailing: false }` - キューに入った実行をスキップ ### 有効化/無効化 -`Throttler`クラスは、`enabled`オプションを通じて有効化/無効化をサポートします。`setOptions`メソッドを使用すると、いつでもスロッターを有効化/無効化できます: +`Throttler`クラスは`enabled`オプションによる有効化/無効化をサポートしています。`setOptions`メソッドを使用して、いつでもスロッターを有効/無効にできます: ```ts const throttler = new Throttler(fn, { wait: 200, enabled: false }) // デフォルトで無効 throttler.setOptions({ enabled: true }) // いつでも有効化 ``` -フレームワークアダプターを使用していてスロッターオプションがリアクティブな場合、`enabled`オプションを条件付きの値に設定することで、スロッターを動的に有効化/無効化できます。ただし、`throttle`関数や`Throttler`クラスを直接使用している場合、`enabled`オプションを変更するには`setOptions`メソッドを使用する必要があります。渡されるオプションは実際には`Throttler`クラスのコンストラクターに渡されるためです。 +スロッターオプションがリアクティブなフレームワークアダプターを使用している場合、`enabled`オプションを条件付きの値に設定して、スロッターを動的に有効/無効にできます。ただし、`throttle`関数や`Throttler`クラスを直接使用している場合は、`setOptions`メソッドを使用して`enabled`オプションを変更する必要があります。渡されるオプションは実際には`Throttler`クラスのコンストラクターに渡されるためです。 ### コールバックオプション -同期型と非同期型の両方のスロッターが、スロットリングライフサイクルのさまざまな側面を処理するためのコールバックオプションをサポートしています: +同期型と非同期型の両方のスロッターが、スロットリングライフサイクルのさまざまな側面を処理するコールバックオプションをサポートしています: -#### 同期型スロッターのコールバック +#### 同期スロッターのコールバック -同期型`Throttler`は以下のコールバックをサポートします: +同期`Throttler`は以下のコールバックをサポートします: ```ts const throttler = new Throttler(fn, { @@ -147,9 +147,9 @@ const throttler = new Throttler(fn, { `onExecute`コールバックは、スロットリングされた関数の各成功実行後に呼び出され、実行の追跡、UI状態の更新、またはクリーンアップ操作の実行に役立ちます。 -#### 非同期型スロッターのコールバック +#### 非同期スロッターのコールバック -非同期型`AsyncThrottler`は、エラー処理のための追加コールバックをサポートします: +非同期`AsyncThrottler`は、エラー処理のための追加コールバックをサポートします: ```ts const asyncThrottler = new AsyncThrottler(async (value) => { @@ -167,37 +167,33 @@ const asyncThrottler = new AsyncThrottler(async (value) => { }) ``` -`onExecute`コールバックは同期型スロッターと同じように機能し、`onError`コールバックではスロットリングチェーンを壊すことなくエラーを適切に処理できます。これらのコールバックは、実行回数の追跡、UI状態の更新、エラー処理、クリーンアップ操作、および実行メトリクスのロギングに特に役立ちます。 +`onExecute`コールバックは同期スロッターと同じように機能し、`onError`コールバックでは、スロットリングチェーンを壊すことなくエラーを適切に処理できます。これらのコールバックは、実行回数の追跡、UI状態の更新、エラー処理、クリーンアップ操作、実行メトリックのロギングに特に役立ちます。 ### 非同期スロットリング -非同期スロッターは、スロットリングを使用して非同期操作を処理する強力な方法を提供し、同期バージョンに比べていくつかの重要な利点があります。同期スロッターがUIイベントや即時のフィードバックに適しているのに対し、非同期バージョンはAPI呼び出し、データベース操作、およびその他の非同期タスクの処理に特化して設計されています。 +非同期スロッターは、スロットリングを使用して非同期操作を処理する強力な方法を提供し、同期バージョンに比べていくつかの重要な利点があります。同期スロッターがUIイベントと即時のフィードバックに適しているのに対し、非同期バージョンはAPI呼び出し、データベース操作、およびその他の非同期タスクの処理に特化して設計されています。 -#### 同期型スロットリングとの主な違い +#### 同期スロットリングとの主な違い 1. **戻り値の処理** -同期スロッターがvoidを返すのとは異なり、非同期バージョンではスロットリングされた関数からの戻り値をキャプチャして使用できます。これは、API呼び出しや他の非同期操作の結果を操作する必要がある場合に特に便利です。`maybeExecute`メソッドは、関数の戻り値で解決されるPromiseを返し、結果を待機して適切に処理できるようにします。 +同期スロッターがvoidを返すのとは異なり、非同期バージョンではスロットリングされた関数からの戻り値をキャプチャして使用できます。これは、API呼び出しやその他の非同期操作の結果を操作する必要がある場合に特に便利です。`maybeExecute`メソッドは、関数の戻り値で解決されるPromiseを返し、結果を待機して適切に処理できるようにします。 -2. **強化されたコールバックシステム** -非同期スロッターは、同期バージョンの単一の`onExecute`コールバックに比べて、より洗練されたコールバックシステムを提供します。このシステムには以下が含まれます: -- `onSuccess`: 非同期関数が正常に完了したときに呼び出され、結果とスロッターインスタンスの両方を提供 -- `onError`: 非同期関数がエラーをスローしたときに呼び出され、エラーとスロッターインスタンスの両方を提供 -- `onSettled`: 成功または失敗にかかわらず、すべての実行試行後に呼び出される +2. **異なるコールバック** +`AsyncThrottler`は、同期バージョンの`onExecute`だけでなく、以下のコールバックをサポートします: +- `onSuccess`: 各成功実行後に呼び出され、スロッターインスタンスを提供 +- `onSettled`: 各実行後に呼び出され、スロッターインスタンスを提供 +- `onError`: 非同期関数がエラーをスローした場合に呼び出され、エラーとスロッターインスタンスの両方を提供 -3. **実行追跡** -非同期スロッターは、いくつかの方法を通じて包括的な実行追跡を提供します: -- `getSuccessCount()`: 成功した実行回数 -- `getErrorCount()`: 失敗した実行回数 -- `getSettledCount()`: 完了した実行の総数(成功 + 失敗) +非同期と同期の両方のスロッターが、成功した実行を処理するための`onExecute`コールバックをサポートしています。 -4. **順次実行** -非同期スロッターは、後続の実行が前の呼び出しの完了を待ってから開始することを保証します。これにより、順不同の実行が防止され、各呼び出しが最新のデータを処理することが保証されます。これは、前の呼び出しの結果に依存する操作や、データの一貫性を維持することが重要な場合に特に重要です。 +3. **順次実行** +スロッターの`maybeExecute`メソッドはPromiseを返すため、次の実行を開始する前に各実行を待機することを選択できます。これにより、実行順序を制御し、各呼び出しが最新のデータを処理することを保証できます。これは、前の呼び出しの結果に依存する操作や、データの一貫性を維持することが重要な場合に特に役立ちます。 -たとえば、ユーザーのプロファイルを更新してからすぐに更新されたデータを取得する場合、非同期スロッターは取得操作が更新の完了を待つようにし、古いデータを取得する可能性のある競合状態を防ぎます。 +たとえば、ユーザーのプロファイルを更新してからすぐに更新されたデータを取得する場合、フェッチ操作を開始する前に更新操作を待機できます: #### 基本的な使用例 -以下は、検索操作に非同期スロッターを使用する基本的な例です: +検索操作に非同期スロッターを使用する基本的な例を以下に示します: ```ts const throttledSearch = asyncThrottle( @@ -220,22 +216,9 @@ const throttledSearch = asyncThrottle( const results = await throttledSearch('query') ``` -#### 高度なパターン - -非同期スロッターは、複雑な問題を解決するためにさまざまなパターンと組み合わせることができます: - -1. **状態管理との統合** -非同期スロッターを状態管理システム(ReactのuseStateやSolidのcreateSignalなど)と組み合わせると、ローディング状態、エラー状態、およびデータ更新を処理する強力なパターンを作成できます。スロッターのコールバックは、操作の成功または失敗に基づいてUI状態を更新するための完璧なフックを提供します。 - -2. **競合状態の防止** -スロットリングパターンは、多くのシナリオで自然に競合状態を防止します。アプリケーションの複数の部分が同時に同じリソースを更新しようとする場合、スロッターは更新が制御された速度で行われることを保証し、すべての呼び出し元に結果を提供します。 - -3. **エラー回復** -非同期スロッターのエラー処理機能は、リトライロジックやエラー回復パターンを実装するのに理想的です。`onError`コールバックを使用して、指数バックオフやフォールバックメカニズムなどのカスタムエラー処理戦略を実装できます。 - ### フレームワークアダプター -各フレームワークアダプターは、コアのスロットリング機能を基盤として構築され、フレームワークの状態管理システムと統合するためのフックを提供します。`createThrottler`、`useThrottledCallback`、`useThrottledState`、`useThrottledValue`などのフックが各フレームワークで利用可能です。 +各フレームワークアダプターは、コアのスロットリング機能を基盤として構築され、フレームワークの状態管理システムと統合するフックを提供します。`createThrottler`、`useThrottledCallback`、`useThrottledState`、`useThrottledValue`などのフックが各フレームワークで利用可能です。 以下にいくつかの例を示します: @@ -256,7 +239,7 @@ const handleUpdate = useThrottledCallback( { wait: 200 } ) -// リアクティブな状態管理のための状態ベースフック +// リアクティブな状態管理のための状態ベースのフック const [instantState, setInstantState] = useState(0) const [throttledValue] = useThrottledValue( instantState, // スロットリングする値 @@ -275,7 +258,7 @@ const throttler = createThrottler( { wait: 200 } ) -// 状態管理のためのシグナルベースフック +// 状態管理のためのシグナルベースのフック const [value, setValue, throttler] = createThrottledSignal(0, { wait: 200, onExecute: (throttler) => { diff --git a/docs/ja/reference/classes/asyncdebouncer.md b/docs/ja/reference/classes/asyncdebouncer.md index 457f166b8..bf584be6a 100644 --- a/docs/ja/reference/classes/asyncdebouncer.md +++ b/docs/ja/reference/classes/asyncdebouncer.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:06:43.605Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:47:46.072Z' id: AsyncDebouncer title: AsyncDebouncer --- @@ -9,7 +9,7 @@ title: AsyncDebouncer # Class: AsyncDebouncer\ -Defined in: [async-debouncer.ts:73](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L73) +Defined in: [async-debouncer.ts:77](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L77) A class that creates an async debounced function. @@ -20,17 +20,21 @@ or input changes where you only want to execute the handler after the events hav Unlike throttling which allows execution at regular intervals, debouncing prevents any execution until the function stops being called for the specified delay period. +Unlike the non-async Debouncer, this async version supports returning values from the debounced function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the debounced function. + ## Example ```ts const asyncDebouncer = new AsyncDebouncer(async (value: string) => { - await searchAPI(value); + const results = await searchAPI(value); + return results; // Return value is preserved }, { wait: 500 }); // Called on each keystroke but only executes after 500ms of no typing -inputElement.addEventListener('input', () => { - asyncDebouncer.maybeExecute(inputElement.value); -}); +// Returns the API response directly +const results = await asyncDebouncer.maybeExecute(inputElement.value); ``` ## Type Parameters @@ -45,7 +49,7 @@ inputElement.addEventListener('input', () => { new AsyncDebouncer(fn, initialOptions): AsyncDebouncer ``` -Defined in: [async-debouncer.ts:86](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L86) +Defined in: [async-debouncer.ts:90](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L90) #### Parameters @@ -69,7 +73,7 @@ Defined in: [async-debouncer.ts:86](https://github.com/TanStack/pacer/blob/main/ cancel(): void ``` -Defined in: [async-debouncer.ts:195](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L195) +Defined in: [async-debouncer.ts:199](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L199) Cancels any pending execution or aborts any execution in progress @@ -85,7 +89,7 @@ Cancels any pending execution or aborts any execution in progress getErrorCount(): number ``` -Defined in: [async-debouncer.ts:224](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L224) +Defined in: [async-debouncer.ts:228](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L228) Returns the number of times the function has errored @@ -101,7 +105,7 @@ Returns the number of times the function has errored getIsExecuting(): boolean ``` -Defined in: [async-debouncer.ts:238](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L238) +Defined in: [async-debouncer.ts:242](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L242) Returns `true` if there is currently an execution in progress @@ -117,7 +121,7 @@ Returns `true` if there is currently an execution in progress getIsPending(): boolean ``` -Defined in: [async-debouncer.ts:231](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L231) +Defined in: [async-debouncer.ts:235](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L235) Returns `true` if there is a pending execution queued up for trailing execution @@ -133,7 +137,7 @@ Returns `true` if there is a pending execution queued up for trailing execution getLastResult(): undefined | ReturnType ``` -Defined in: [async-debouncer.ts:203](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L203) +Defined in: [async-debouncer.ts:207](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L207) Returns the last result of the debounced function @@ -149,7 +153,7 @@ Returns the last result of the debounced function getOptions(): Required> ``` -Defined in: [async-debouncer.ts:112](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L112) +Defined in: [async-debouncer.ts:116](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L116) Returns the current debouncer options @@ -165,7 +169,7 @@ Returns the current debouncer options getSettleCount(): number ``` -Defined in: [async-debouncer.ts:217](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L217) +Defined in: [async-debouncer.ts:221](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L221) Returns the number of times the function has settled (completed or errored) @@ -181,7 +185,7 @@ Returns the number of times the function has settled (completed or errored) getSuccessCount(): number ``` -Defined in: [async-debouncer.ts:210](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L210) +Defined in: [async-debouncer.ts:214](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L214) Returns the number of times the function has been executed successfully @@ -197,7 +201,7 @@ Returns the number of times the function has been executed successfully maybeExecute(...args): Promise> ``` -Defined in: [async-debouncer.ts:120](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L120) +Defined in: [async-debouncer.ts:124](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L124) Attempts to execute the debounced function If a call is already in progress, it will be queued @@ -220,7 +224,7 @@ If a call is already in progress, it will be queued setOptions(newOptions): void ``` -Defined in: [async-debouncer.ts:100](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L100) +Defined in: [async-debouncer.ts:104](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L104) Updates the debouncer options Returns the new options state diff --git a/docs/ja/reference/classes/asyncratelimiter.md b/docs/ja/reference/classes/asyncratelimiter.md index a6a5f7bc7..2b01c2a56 100644 --- a/docs/ja/reference/classes/asyncratelimiter.md +++ b/docs/ja/reference/classes/asyncratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:06:43.596Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:47:46.069Z' id: AsyncRateLimiter title: AsyncRateLimiter --- @@ -9,7 +9,7 @@ title: AsyncRateLimiter # Class: AsyncRateLimiter\ -Defined in: [async-rate-limiter.ts:76](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L76) +Defined in: [async-rate-limiter.ts:95](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L95) A class that creates an async rate-limited function. @@ -17,6 +17,16 @@ Rate limiting is a simple approach that allows a function to execute up to a lim then blocks all subsequent calls until the window passes. This can lead to "bursty" behavior where all executions happen immediately, followed by a complete block. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + +Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + For smoother execution patterns, consider using: - Throttling: Ensures consistent spacing between executions (e.g. max once per 200ms) - Debouncing: Waits for a pause in calls before executing (e.g. after 500ms of no calls) @@ -29,11 +39,12 @@ smoothing out frequent events, throttling or debouncing usually provide better u ```ts const rateLimiter = new AsyncRateLimiter( async (id: string) => await api.getData(id), - { limit: 5, window: 1000 } // 5 calls per second + { limit: 5, window: 1000, windowType: 'sliding' } // 5 calls per second with sliding window ); // Will execute immediately until limit reached, then block -await rateLimiter.maybeExecute('123'); +// Returns the API response directly +const data = await rateLimiter.maybeExecute('123'); ``` ## Type Parameters @@ -48,7 +59,7 @@ await rateLimiter.maybeExecute('123'); new AsyncRateLimiter(fn, initialOptions): AsyncRateLimiter ``` -Defined in: [async-rate-limiter.ts:85](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L85) +Defined in: [async-rate-limiter.ts:105](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L105) #### Parameters @@ -72,7 +83,7 @@ Defined in: [async-rate-limiter.ts:85](https://github.com/TanStack/pacer/blob/ma getErrorCount(): number ``` -Defined in: [async-rate-limiter.ts:209](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L209) +Defined in: [async-rate-limiter.ts:250](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L250) Returns the number of times the function has errored @@ -82,15 +93,33 @@ Returns the number of times the function has errored *** +### getIsExecuting() + +```ts +getIsExecuting(): boolean +``` + +Defined in: [async-rate-limiter.ts:264](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L264) + +Returns whether the function is currently executing + +#### Returns + +`boolean` + +*** + ### getMsUntilNextWindow() ```ts getMsUntilNextWindow(): number ``` -Defined in: [async-rate-limiter.ts:188](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L188) +Defined in: [async-rate-limiter.ts:225](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L225) Returns the number of milliseconds until the next execution will be possible +For fixed windows, this is the time until the current window resets +For sliding windows, this is the time until the oldest execution expires #### Returns @@ -104,7 +133,7 @@ Returns the number of milliseconds until the next execution will be possible getOptions(): Required> ``` -Defined in: [async-rate-limiter.ts:106](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L106) +Defined in: [async-rate-limiter.ts:126](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L126) Returns the current rate limiter options @@ -120,7 +149,7 @@ Returns the current rate limiter options getRejectionCount(): number ``` -Defined in: [async-rate-limiter.ts:216](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L216) +Defined in: [async-rate-limiter.ts:257](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L257) Returns the number of times the function has been rejected @@ -136,7 +165,7 @@ Returns the number of times the function has been rejected getRemainingInWindow(): number ``` -Defined in: [async-rate-limiter.ts:180](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L180) +Defined in: [async-rate-limiter.ts:215](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L215) Returns the number of remaining executions allowed in the current window @@ -152,7 +181,7 @@ Returns the number of remaining executions allowed in the current window getSettleCount(): number ``` -Defined in: [async-rate-limiter.ts:202](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L202) +Defined in: [async-rate-limiter.ts:243](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L243) Returns the number of times the function has been settled @@ -168,7 +197,7 @@ Returns the number of times the function has been settled getSuccessCount(): number ``` -Defined in: [async-rate-limiter.ts:195](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L195) +Defined in: [async-rate-limiter.ts:236](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L236) Returns the number of times the function has been executed @@ -184,7 +213,7 @@ Returns the number of times the function has been executed maybeExecute(...args): Promise> ``` -Defined in: [async-rate-limiter.ts:126](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L126) +Defined in: [async-rate-limiter.ts:146](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L146) Attempts to execute the rate-limited function if within the configured limits. Will reject execution if the number of calls in the current window exceeds the limit. @@ -220,7 +249,7 @@ await rateLimiter.maybeExecute('arg1', 'arg2'); // Rejected reset(): void ``` -Defined in: [async-rate-limiter.ts:223](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L223) +Defined in: [async-rate-limiter.ts:271](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L271) Resets the rate limiter state @@ -236,7 +265,7 @@ Resets the rate limiter state setOptions(newOptions): void ``` -Defined in: [async-rate-limiter.ts:99](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L99) +Defined in: [async-rate-limiter.ts:119](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L119) Updates the rate limiter options Returns the new options state diff --git a/docs/ja/reference/classes/asyncthrottler.md b/docs/ja/reference/classes/asyncthrottler.md index f1a8ec136..c465ea686 100644 --- a/docs/ja/reference/classes/asyncthrottler.md +++ b/docs/ja/reference/classes/asyncthrottler.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:06:43.590Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:47:46.065Z' id: AsyncThrottler title: AsyncThrottler --- @@ -9,7 +9,7 @@ title: AsyncThrottler # Class: AsyncThrottler\ -Defined in: [async-throttler.ts:76](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L76) +Defined in: [async-throttler.ts:80](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L80) A class that creates an async throttled function. @@ -17,6 +17,10 @@ Throttling limits how often a function can be executed, allowing only one execut Unlike debouncing which resets the delay timer on each call, throttling ensures the function executes at a regular interval regardless of how often it's called. +Unlike the non-async Throttler, this async version supports returning values from the throttled function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the throttled function. + This is useful for rate-limiting API calls, handling scroll/resize events, or any scenario where you want to ensure a maximum execution frequency. @@ -24,13 +28,13 @@ ensure a maximum execution frequency. ```ts const throttler = new AsyncThrottler(async (value: string) => { - await saveToAPI(value); + const result = await saveToAPI(value); + return result; // Return value is preserved }, { wait: 1000 }); // Will only execute once per second no matter how often called -inputElement.addEventListener('input', () => { - throttler.maybeExecute(inputElement.value); -}); +// Returns the API response directly +const result = await throttler.maybeExecute(inputElement.value); ``` ## Type Parameters @@ -45,7 +49,7 @@ inputElement.addEventListener('input', () => { new AsyncThrottler(fn, initialOptions): AsyncThrottler ``` -Defined in: [async-throttler.ts:89](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L89) +Defined in: [async-throttler.ts:93](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L93) #### Parameters @@ -69,7 +73,7 @@ Defined in: [async-throttler.ts:89](https://github.com/TanStack/pacer/blob/main/ cancel(): void ``` -Defined in: [async-throttler.ts:187](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L187) +Defined in: [async-throttler.ts:191](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L191) Cancels any pending execution or aborts any execution in progress @@ -85,7 +89,7 @@ Cancels any pending execution or aborts any execution in progress getErrorCount(): number ``` -Defined in: [async-throttler.ts:237](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L237) +Defined in: [async-throttler.ts:241](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L241) Returns the number of times the function has errored @@ -101,7 +105,7 @@ Returns the number of times the function has errored getIsExecuting(): boolean ``` -Defined in: [async-throttler.ts:251](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L251) +Defined in: [async-throttler.ts:255](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L255) Returns the current executing state @@ -117,7 +121,7 @@ Returns the current executing state getIsPending(): boolean ``` -Defined in: [async-throttler.ts:244](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L244) +Defined in: [async-throttler.ts:248](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L248) Returns the current pending state @@ -133,7 +137,7 @@ Returns the current pending state getLastExecutionTime(): number ``` -Defined in: [async-throttler.ts:202](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L202) +Defined in: [async-throttler.ts:206](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L206) Returns the last execution time @@ -149,7 +153,7 @@ Returns the last execution time getLastResult(): undefined | ReturnType ``` -Defined in: [async-throttler.ts:216](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L216) +Defined in: [async-throttler.ts:220](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L220) Returns the last result of the debounced function @@ -165,7 +169,7 @@ Returns the last result of the debounced function getNextExecutionTime(): number ``` -Defined in: [async-throttler.ts:209](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L209) +Defined in: [async-throttler.ts:213](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L213) Returns the next execution time @@ -181,7 +185,7 @@ Returns the next execution time getOptions(): Required> ``` -Defined in: [async-throttler.ts:115](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L115) +Defined in: [async-throttler.ts:119](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L119) Returns the current options @@ -197,7 +201,7 @@ Returns the current options getSettleCount(): number ``` -Defined in: [async-throttler.ts:230](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L230) +Defined in: [async-throttler.ts:234](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L234) Returns the number of times the function has settled (completed or errored) @@ -213,7 +217,7 @@ Returns the number of times the function has settled (completed or errored) getSuccessCount(): number ``` -Defined in: [async-throttler.ts:223](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L223) +Defined in: [async-throttler.ts:227](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L227) Returns the number of times the function has been executed successfully @@ -229,7 +233,7 @@ Returns the number of times the function has been executed successfully maybeExecute(...args): Promise> ``` -Defined in: [async-throttler.ts:123](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L123) +Defined in: [async-throttler.ts:127](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L127) Attempts to execute the throttled function If a call is already in progress, it may be blocked or queued depending on the `wait` option @@ -252,7 +256,7 @@ If a call is already in progress, it may be blocked or queued depending on the ` setOptions(newOptions): void ``` -Defined in: [async-throttler.ts:103](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L103) +Defined in: [async-throttler.ts:107](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L107) Updates the throttler options Returns the new options state diff --git a/docs/ja/reference/classes/ratelimiter.md b/docs/ja/reference/classes/ratelimiter.md index a00187ab1..9424a8256 100644 --- a/docs/ja/reference/classes/ratelimiter.md +++ b/docs/ja/reference/classes/ratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:06:43.573Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:47:46.054Z' id: RateLimiter title: RateLimiter --- @@ -9,7 +9,7 @@ title: RateLimiter # Class: RateLimiter\ -Defined in: [rate-limiter.ts:63](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L63) +Defined in: [rate-limiter.ts:77](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L77) A class that creates a rate-limited function. @@ -17,6 +17,12 @@ Rate limiting is a simple approach that allows a function to execute up to a lim then blocks all subsequent calls until the window passes. This can lead to "bursty" behavior where all executions happen immediately, followed by a complete block. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns, consider using: - Throttling: Ensures consistent spacing between executions (e.g. max once per 200ms) - Debouncing: Waits for a pause in calls before executing (e.g. after 500ms of no calls) @@ -29,7 +35,7 @@ smoothing out frequent events, throttling or debouncing usually provide better u ```ts const rateLimiter = new RateLimiter( (id: string) => api.getData(id), - { limit: 5, window: 1000 } // 5 calls per second + { limit: 5, window: 1000, windowType: 'sliding' } // 5 calls per second with sliding window ); // Will execute immediately until limit reached, then block @@ -48,7 +54,7 @@ rateLimiter.maybeExecute('123'); new RateLimiter(fn, initialOptions): RateLimiter ``` -Defined in: [rate-limiter.ts:69](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L69) +Defined in: [rate-limiter.ts:83](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L83) #### Parameters @@ -72,7 +78,7 @@ Defined in: [rate-limiter.ts:69](https://github.com/TanStack/pacer/blob/main/pac getExecutionCount(): number ``` -Defined in: [rate-limiter.ts:149](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L149) +Defined in: [rate-limiter.ts:175](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L175) Returns the number of times the function has been executed @@ -88,7 +94,7 @@ Returns the number of times the function has been executed getMsUntilNextWindow(): number ``` -Defined in: [rate-limiter.ts:171](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L171) +Defined in: [rate-limiter.ts:197](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L197) Returns the number of milliseconds until the next execution will be possible @@ -104,7 +110,7 @@ Returns the number of milliseconds until the next execution will be possible getOptions(): Required> ``` -Defined in: [rate-limiter.ts:90](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L90) +Defined in: [rate-limiter.ts:104](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L104) Returns the current rate limiter options @@ -120,7 +126,7 @@ Returns the current rate limiter options getRejectionCount(): number ``` -Defined in: [rate-limiter.ts:156](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L156) +Defined in: [rate-limiter.ts:182](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L182) Returns the number of times the function has been rejected @@ -136,7 +142,7 @@ Returns the number of times the function has been rejected getRemainingInWindow(): number ``` -Defined in: [rate-limiter.ts:163](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L163) +Defined in: [rate-limiter.ts:189](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L189) Returns the number of remaining executions allowed in the current window @@ -152,7 +158,7 @@ Returns the number of remaining executions allowed in the current window maybeExecute(...args): boolean ``` -Defined in: [rate-limiter.ts:109](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L109) +Defined in: [rate-limiter.ts:123](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L123) Attempts to execute the rate-limited function if within the configured limits. Will reject execution if the number of calls in the current window exceeds the limit. @@ -187,7 +193,7 @@ rateLimiter.maybeExecute('arg1', 'arg2'); // false reset(): void ``` -Defined in: [rate-limiter.ts:179](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L179) +Defined in: [rate-limiter.ts:208](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L208) Resets the rate limiter state @@ -203,7 +209,7 @@ Resets the rate limiter state setOptions(newOptions): void ``` -Defined in: [rate-limiter.ts:83](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L83) +Defined in: [rate-limiter.ts:97](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L97) Updates the rate limiter options Returns the new options state diff --git a/docs/ja/reference/functions/asyncdebounce.md b/docs/ja/reference/functions/asyncdebounce.md index 170b4e49b..99fdd19c1 100644 --- a/docs/ja/reference/functions/asyncdebounce.md +++ b/docs/ja/reference/functions/asyncdebounce.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-04-24T02:14:56.000Z' -translation-updated-at: '2025-05-06T20:30:24.117Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:47:46.050Z' id: asyncDebounce title: asyncDebounce --- @@ -10,21 +10,23 @@ title: asyncDebounce # Function: asyncDebounce() ```ts -function asyncDebounce(fn, initialOptions): (...args) => Promise +function asyncDebounce(fn, initialOptions): (...args) => Promise> ``` -Defined in: [async-debouncer.ts:219](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L219) +Defined in: [async-debouncer.ts:268](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L268) Creates an async debounced function that delays execution until after a specified wait time. The debounced function will only execute once the wait period has elapsed without any new calls. If called again during the wait period, the timer resets and a new wait period begins. +Unlike the non-async Debouncer, this async version supports returning values from the debounced function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the debounced function. + ## Type Parameters • **TFn** *extends* [`AnyAsyncFunction`](../type-aliases/anyasyncfunction.md) -• **TArgs** *extends* `any`[] - ## Parameters ### fn @@ -33,7 +35,7 @@ If called again during the wait period, the timer resets and a new wait period b ### initialOptions -`Omit`\<[`AsyncDebouncerOptions`](../interfaces/asyncdebounceroptions.md)\<`TFn`, `TArgs`\>, `"enabled"`\> +`Omit`\<[`AsyncDebouncerOptions`](../interfaces/asyncdebounceroptions.md)\<`TFn`\>, `"enabled"`\> ## Returns @@ -46,21 +48,21 @@ If a call is already in progress, it will be queued #### args -...`TArgs` +...`Parameters`\<`TFn`\> ### Returns -`Promise`\<`void`\> +`Promise`\<`undefined` \| `ReturnType`\<`TFn`\>\> ## Example ```ts const debounced = asyncDebounce(async (value: string) => { - await saveToAPI(value); + const result = await saveToAPI(value); + return result; // Return value is preserved }, { wait: 1000 }); // Will only execute once, 1 second after the last call -await debounced("first"); // Cancelled -await debounced("second"); // Cancelled -await debounced("third"); // Executes after 1s +// Returns the API response directly +const result = await debounced("third"); ``` diff --git a/docs/ja/reference/functions/asyncratelimit.md b/docs/ja/reference/functions/asyncratelimit.md index 916269b28..aa1539dfa 100644 --- a/docs/ja/reference/functions/asyncratelimit.md +++ b/docs/ja/reference/functions/asyncratelimit.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:06:43.564Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:47:46.046Z' id: asyncRateLimit title: asyncRateLimit --- @@ -13,10 +13,20 @@ title: asyncRateLimit function asyncRateLimit(fn, initialOptions): (...args) => Promise> ``` -Defined in: [async-rate-limiter.ts:262](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L262) +Defined in: [async-rate-limiter.ts:322](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L322) Creates an async rate-limited function that will execute the provided function up to a maximum number of times within a time window. +Unlike the non-async rate limiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + Note that rate limiting is a simpler form of execution control compared to throttling or debouncing: - A rate limiter will allow all executions until the limit is reached, then block all subsequent calls until the window resets - A throttler ensures even spacing between executions, which can be better for consistent performance @@ -72,10 +82,11 @@ await rateLimiter.maybeExecute('arg1', 'arg2'); // Rejected ## Example ```ts -// Rate limit to 5 calls per minute +// Rate limit to 5 calls per minute with a sliding window const rateLimited = asyncRateLimit(makeApiCall, { limit: 5, window: 60000, + windowType: 'sliding', onReject: (rateLimiter) => { console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } @@ -83,7 +94,8 @@ const rateLimited = asyncRateLimit(makeApiCall, { // First 5 calls will execute immediately // Additional calls will be rejected until the minute window resets -await rateLimited(); +// Returns the API response directly +const result = await rateLimited(); // For more even execution, consider using throttle instead: const throttled = throttle(makeApiCall, { wait: 12000 }); // One call every 12 seconds diff --git a/docs/ja/reference/functions/asyncthrottle.md b/docs/ja/reference/functions/asyncthrottle.md index eb1512200..1e6e3d52f 100644 --- a/docs/ja/reference/functions/asyncthrottle.md +++ b/docs/ja/reference/functions/asyncthrottle.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-04-24T02:14:56.000Z' -translation-updated-at: '2025-05-06T20:30:24.108Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:47:46.043Z' id: asyncThrottle title: asyncThrottle --- @@ -10,21 +10,23 @@ title: asyncThrottle # Function: asyncThrottle() ```ts -function asyncThrottle(fn, initialOptions): (...args) => Promise +function asyncThrottle(fn, initialOptions): (...args) => Promise> ``` -Defined in: [async-throttler.ts:223](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L223) +Defined in: [async-throttler.ts:281](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L281) Creates an async throttled function that limits how often the function can execute. The throttled function will execute at most once per wait period, even if called multiple times. If called while executing, it will wait until execution completes before scheduling the next call. +Unlike the non-async Throttler, this async version supports returning values from the throttled function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the throttled function. + ## Type Parameters • **TFn** *extends* [`AnyAsyncFunction`](../type-aliases/anyasyncfunction.md) -• **TArgs** *extends* `any`[] - ## Parameters ### fn @@ -33,7 +35,7 @@ If called while executing, it will wait until execution completes before schedul ### initialOptions -`Omit`\<[`AsyncThrottlerOptions`](../interfaces/asyncthrottleroptions.md)\<`TFn`, `TArgs`\>, `"enabled"`\> +`Omit`\<[`AsyncThrottlerOptions`](../interfaces/asyncthrottleroptions.md)\<`TFn`\>, `"enabled"`\> ## Returns @@ -46,20 +48,21 @@ If a call is already in progress, it may be blocked or queued depending on the ` #### args -...`TArgs` +...`Parameters`\<`TFn`\> ### Returns -`Promise`\<`void`\> +`Promise`\<`undefined` \| `ReturnType`\<`TFn`\>\> ## Example ```ts -const throttled = asyncThrottle(async () => { - await someAsyncOperation(); +const throttled = asyncThrottle(async (value: string) => { + const result = await saveToAPI(value); + return result; // Return value is preserved }, { wait: 1000 }); // This will execute at most once per second -await throttled(); -await throttled(); // Waits 1 second before executing +// Returns the API response directly +const result = await throttled(inputElement.value); ``` diff --git a/docs/ja/reference/functions/ratelimit.md b/docs/ja/reference/functions/ratelimit.md index 8cbacd2ab..d4fe2302e 100644 --- a/docs/ja/reference/functions/ratelimit.md +++ b/docs/ja/reference/functions/ratelimit.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:06:43.556Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:47:46.039Z' id: rateLimit title: rateLimit --- @@ -13,7 +13,7 @@ title: rateLimit function rateLimit(fn, initialOptions): (...args) => boolean ``` -Defined in: [rate-limiter.ts:216](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L216) +Defined in: [rate-limiter.ts:252](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L252) Creates a rate-limited function that will execute the provided function up to a maximum number of times within a time window. @@ -22,6 +22,12 @@ Note that rate limiting is a simpler form of execution control compared to throt - A throttler ensures even spacing between executions, which can be better for consistent performance - A debouncer collapses multiple calls into one, which is better for handling bursts of events +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + Consider using throttle() or debounce() if you need more intelligent execution control. Use rate limiting when you specifically need to enforce a hard limit on the number of executions within a time period. @@ -71,10 +77,11 @@ rateLimiter.maybeExecute('arg1', 'arg2'); // false ## Example ```ts -// Rate limit to 5 calls per minute +// Rate limit to 5 calls per minute with a sliding window const rateLimited = rateLimit(makeApiCall, { limit: 5, window: 60000, + windowType: 'sliding', onReject: (rateLimiter) => { console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/ja/reference/interfaces/asyncratelimiteroptions.md b/docs/ja/reference/interfaces/asyncratelimiteroptions.md index faa1b192d..8df9201f1 100644 --- a/docs/ja/reference/interfaces/asyncratelimiteroptions.md +++ b/docs/ja/reference/interfaces/asyncratelimiteroptions.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:06:43.537Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:47:46.035Z' id: AsyncRateLimiterOptions title: AsyncRateLimiterOptions --- @@ -149,3 +149,18 @@ window: number; Defined in: [async-rate-limiter.ts:38](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L38) Time window in milliseconds within which the limit applies + +*** + +### windowType? + +```ts +optional windowType: "fixed" | "sliding"; +``` + +Defined in: [async-rate-limiter.ts:45](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L45) + +Type of window to use for rate limiting +- 'fixed': Uses a fixed window that resets after the window period +- 'sliding': Uses a sliding window that allows executions as old ones expire +Defaults to 'fixed' diff --git a/docs/ja/reference/interfaces/ratelimiteroptions.md b/docs/ja/reference/interfaces/ratelimiteroptions.md index bad2f9c21..fe14811f9 100644 --- a/docs/ja/reference/interfaces/ratelimiteroptions.md +++ b/docs/ja/reference/interfaces/ratelimiteroptions.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:06:43.506Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:47:46.032Z' id: RateLimiterOptions title: RateLimiterOptions --- @@ -97,3 +97,18 @@ window: number; Defined in: [rate-limiter.ts:27](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L27) Time window in milliseconds within which the limit applies + +*** + +### windowType? + +```ts +optional windowType: "fixed" | "sliding"; +``` + +Defined in: [rate-limiter.ts:34](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L34) + +Type of window to use for rate limiting +- 'fixed': Uses a fixed window that resets after the window period +- 'sliding': Uses a sliding window that allows executions as old ones expire +Defaults to 'fixed' diff --git a/docs/ru/framework/react/reference/functions/useasyncratelimiter.md b/docs/ru/framework/react/reference/functions/useasyncratelimiter.md index 68b272984..95ef00c77 100644 --- a/docs/ru/framework/react/reference/functions/useasyncratelimiter.md +++ b/docs/ru/framework/react/reference/functions/useasyncratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:17:21.270Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:59:36.090Z' id: useAsyncRateLimiter title: useAsyncRateLimiter --- @@ -13,7 +13,7 @@ title: useAsyncRateLimiter function useAsyncRateLimiter(fn, options): AsyncRateLimiter ``` -Defined in: [react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts:43](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts#L43) +Defined in: [react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts:54](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts#L54) A low-level React hook that creates an `AsyncRateLimiter` instance to limit how many times an async function can execute within a time window. @@ -24,6 +24,16 @@ Rate limiting allows an async function to execute up to a specified limit within then blocks subsequent calls until the window passes. This is useful for respecting API rate limits, managing resource constraints, or controlling bursts of async operations. +Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + ## Type Parameters • **TFn** *extends* `AnyAsyncFunction` @@ -45,21 +55,22 @@ managing resource constraints, or controlling bursts of async operations. ## Example ```tsx -// Basic API call rate limiting +// Basic API call rate limiting with return value const { maybeExecute } = useAsyncRateLimiter( async (id: string) => { const data = await api.fetchData(id); - return data; + return data; // Return value is preserved }, { limit: 5, window: 1000 } // 5 calls per second ); -// With state management +// With state management and return value const [data, setData] = useState(null); const { maybeExecute } = useAsyncRateLimiter( async (query) => { const result = await searchAPI(query); setData(result); + return result; // Return value can be used by the caller }, { limit: 10, diff --git a/docs/ru/framework/react/reference/functions/useratelimitedcallback.md b/docs/ru/framework/react/reference/functions/useratelimitedcallback.md index db5afd166..127109405 100644 --- a/docs/ru/framework/react/reference/functions/useratelimitedcallback.md +++ b/docs/ru/framework/react/reference/functions/useratelimitedcallback.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-04-24T02:14:56.000Z' -translation-updated-at: '2025-05-06T20:43:58.752Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:59:36.086Z' id: useRateLimitedCallback title: useRateLimitedCallback --- @@ -13,7 +13,7 @@ title: useRateLimitedCallback function useRateLimitedCallback(fn, options): (...args) => boolean ``` -Defined in: [rate-limiter/useRateLimitedCallback.ts:52](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedCallback.ts#L52) +Defined in: [react-pacer/src/rate-limiter/useRateLimitedCallback.ts:59](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedCallback.ts#L59) A React hook that creates a rate-limited version of a callback function. This hook is essentially a wrapper around the basic `rateLimiter` function @@ -26,6 +26,12 @@ or debouncing, it does not attempt to space out or intelligently collapse calls. This can lead to bursts of rapid executions followed by periods where all calls are blocked. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns, consider: - useThrottledCallback: When you want consistent spacing between executions (e.g. UI updates) - useDebouncedCallback: When you want to collapse rapid calls into a single execution (e.g. search input) @@ -57,7 +63,7 @@ Consider using the `useRateLimiter` hook instead. ### options -`RateLimiterOptions`\<`TFn`, `TArgs`\> +`RateLimiterOptions`\<`TFn`\> ## Returns @@ -76,7 +82,7 @@ Consider using the `useRateLimiter` hook instead. ## Example ```tsx -// Rate limit API calls to maximum 5 calls per minute +// Rate limit API calls to maximum 5 calls per minute with a sliding window const makeApiCall = useRateLimitedCallback( (data: ApiData) => { return fetch('/api/endpoint', { method: 'POST', body: JSON.stringify(data) }); @@ -84,6 +90,7 @@ const makeApiCall = useRateLimitedCallback( { limit: 5, window: 60000, // 1 minute + windowType: 'sliding', onReject: () => { console.warn('API rate limit reached. Please wait before trying again.'); } diff --git a/docs/ru/framework/react/reference/functions/useratelimitedstate.md b/docs/ru/framework/react/reference/functions/useratelimitedstate.md index eb85125a4..459559609 100644 --- a/docs/ru/framework/react/reference/functions/useratelimitedstate.md +++ b/docs/ru/framework/react/reference/functions/useratelimitedstate.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:17:21.233Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:59:36.082Z' id: useRateLimitedState title: useRateLimitedState --- @@ -13,7 +13,7 @@ title: useRateLimitedState function useRateLimitedState(value, options): [TValue, Dispatch>, RateLimiter>>] ``` -Defined in: [react-pacer/src/rate-limiter/useRateLimitedState.ts:59](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedState.ts#L59) +Defined in: [react-pacer/src/rate-limiter/useRateLimitedState.ts:66](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedState.ts#L66) A React hook that creates a rate-limited state value that enforces a hard limit on state updates within a time window. This hook combines React's useState with rate limiting functionality to provide controlled state updates. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - useThrottledState: When you want consistent spacing between updates (e.g. UI changes) - useDebouncedState: When you want to collapse rapid updates into a single update (e.g. search input) @@ -57,16 +63,18 @@ consider using the lower-level useRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update state at most 5 times per minute +// Basic rate limiting - update state at most 5 times per minute with a sliding window const [value, setValue, rateLimiter] = useRateLimitedState(0, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); -// With rejection callback +// With rejection callback and fixed window const [value, setValue] = useRateLimitedState(0, { limit: 3, window: 5000, + windowType: 'fixed', onReject: (rateLimiter) => { alert(`Rate limit reached. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/ru/framework/react/reference/functions/useratelimitedvalue.md b/docs/ru/framework/react/reference/functions/useratelimitedvalue.md index 96c4f4161..68b73782d 100644 --- a/docs/ru/framework/react/reference/functions/useratelimitedvalue.md +++ b/docs/ru/framework/react/reference/functions/useratelimitedvalue.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:17:21.229Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:59:36.079Z' id: useRateLimitedValue title: useRateLimitedValue --- @@ -13,7 +13,7 @@ title: useRateLimitedValue function useRateLimitedValue(value, options): [TValue, RateLimiter>>] ``` -Defined in: [react-pacer/src/rate-limiter/useRateLimitedValue.ts:47](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedValue.ts#L47) +Defined in: [react-pacer/src/rate-limiter/useRateLimitedValue.ts:55](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedValue.ts#L55) A high-level React hook that creates a rate-limited version of a value that updates at most a certain number of times within a time window. This hook uses React's useState internally to manage the rate-limited state. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - useThrottledValue: When you want consistent spacing between updates (e.g. UI changes) - useDebouncedValue: When you want to collapse rapid updates into a single update (e.g. search input) @@ -56,16 +62,18 @@ consider using the lower-level useRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update at most 5 times per minute +// Basic rate limiting - update at most 5 times per minute with a sliding window const [rateLimitedValue, rateLimiter] = useRateLimitedValue(rawValue, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); -// With rejection callback +// With rejection callback and fixed window const [rateLimitedValue, rateLimiter] = useRateLimitedValue(rawValue, { limit: 3, window: 5000, + windowType: 'fixed', onReject: (rateLimiter) => { console.log(`Update rejected. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/ru/framework/react/reference/functions/useratelimiter.md b/docs/ru/framework/react/reference/functions/useratelimiter.md index abe0136a6..52fbcc313 100644 --- a/docs/ru/framework/react/reference/functions/useratelimiter.md +++ b/docs/ru/framework/react/reference/functions/useratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:17:21.225Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:59:36.074Z' id: useRateLimiter title: useRateLimiter --- @@ -13,7 +13,7 @@ title: useRateLimiter function useRateLimiter(fn, options): RateLimiter ``` -Defined in: [react-pacer/src/rate-limiter/useRateLimiter.ts:48](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimiter.ts#L48) +Defined in: [react-pacer/src/rate-limiter/useRateLimiter.ts:55](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimiter.ts#L55) A low-level React hook that creates a `RateLimiter` instance to enforce rate limits on function execution. @@ -24,6 +24,12 @@ Rate limiting is a simple "hard limit" approach that allows executions until a m a time window, then blocks all subsequent calls until the window resets. Unlike throttling or debouncing, it does not attempt to space out or collapse executions intelligently. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns: - Use throttling when you want consistent spacing between executions (e.g. UI updates) - Use debouncing when you want to collapse rapid-fire events (e.g. search input) @@ -57,10 +63,11 @@ The hook returns an object containing: ## Example ```tsx -// Basic rate limiting - max 5 calls per minute +// Basic rate limiting - max 5 calls per minute with a sliding window const { maybeExecute } = useRateLimiter(apiCall, { limit: 5, window: 60000, + windowType: 'sliding', }); // Monitor rate limit status diff --git a/docs/ru/framework/solid/reference/functions/createasyncratelimiter.md b/docs/ru/framework/solid/reference/functions/createasyncratelimiter.md index 6aec053d1..711402b78 100644 --- a/docs/ru/framework/solid/reference/functions/createasyncratelimiter.md +++ b/docs/ru/framework/solid/reference/functions/createasyncratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:17:21.197Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:59:36.069Z' id: createAsyncRateLimiter title: createAsyncRateLimiter --- @@ -13,7 +13,7 @@ title: createAsyncRateLimiter function createAsyncRateLimiter(fn, initialOptions): SolidAsyncRateLimiter ``` -Defined in: [async-rate-limiter/createAsyncRateLimiter.ts:62](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L62) +Defined in: [async-rate-limiter/createAsyncRateLimiter.ts:73](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L73) A low-level Solid hook that creates an `AsyncRateLimiter` instance to limit how many times an async function can execute within a time window. @@ -24,6 +24,16 @@ Rate limiting allows an async function to execute up to a specified limit within then blocks subsequent calls until the window passes. This is useful for respecting API rate limits, managing resource constraints, or controlling bursts of async operations. +Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + ## Type Parameters • **TFn** *extends* `AnyAsyncFunction` @@ -45,21 +55,22 @@ managing resource constraints, or controlling bursts of async operations. ## Example ```tsx -// Basic API call rate limiting +// Basic API call rate limiting with return value const { maybeExecute } = createAsyncRateLimiter( async (id: string) => { const data = await api.fetchData(id); - return data; + return data; // Return value is preserved }, { limit: 5, window: 1000 } // 5 calls per second ); -// With state management +// With state management and return value const [data, setData] = createSignal(null); const { maybeExecute } = createAsyncRateLimiter( async (query) => { const result = await searchAPI(query); setData(result); + return result; // Return value can be used by the caller }, { limit: 10, diff --git a/docs/ru/framework/solid/reference/functions/createratelimitedsignal.md b/docs/ru/framework/solid/reference/functions/createratelimitedsignal.md index 9455b42d8..febdadcdc 100644 --- a/docs/ru/framework/solid/reference/functions/createratelimitedsignal.md +++ b/docs/ru/framework/solid/reference/functions/createratelimitedsignal.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:17:21.173Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:59:36.065Z' id: createRateLimitedSignal title: createRateLimitedSignal --- @@ -13,7 +13,7 @@ title: createRateLimitedSignal function createRateLimitedSignal(value, initialOptions): [Accessor, Setter, SolidRateLimiter>] ``` -Defined in: [rate-limiter/createRateLimitedSignal.ts:57](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedSignal.ts#L57) +Defined in: [rate-limiter/createRateLimitedSignal.ts:65](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedSignal.ts#L65) A Solid hook that creates a rate-limited state value that enforces a hard limit on state updates within a time window. This hook combines Solid's createSignal with rate limiting functionality to provide controlled state updates. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - createThrottledSignal: When you want consistent spacing between updates (e.g. UI changes) - createDebouncedSignal: When you want to collapse rapid updates into a single update (e.g. search input) @@ -57,16 +63,18 @@ consider using the lower-level createRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update state at most 5 times per minute +// Basic rate limiting - update state at most 5 times per minute with a sliding window const [value, setValue, rateLimiter] = createRateLimitedSignal(0, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); -// With rejection callback +// With rejection callback and fixed window const [value, setValue] = createRateLimitedSignal(0, { limit: 3, window: 5000, + windowType: 'fixed', onReject: (rateLimiter) => { alert(`Rate limit reached. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/ru/framework/solid/reference/functions/createratelimitedvalue.md b/docs/ru/framework/solid/reference/functions/createratelimitedvalue.md index e7bebfb34..2b88ba08f 100644 --- a/docs/ru/framework/solid/reference/functions/createratelimitedvalue.md +++ b/docs/ru/framework/solid/reference/functions/createratelimitedvalue.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:17:21.168Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:59:36.061Z' id: createRateLimitedValue title: createRateLimitedValue --- @@ -13,7 +13,7 @@ title: createRateLimitedValue function createRateLimitedValue(value, initialOptions): [Accessor, SolidRateLimiter>] ``` -Defined in: [rate-limiter/createRateLimitedValue.ts:43](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedValue.ts#L43) +Defined in: [rate-limiter/createRateLimitedValue.ts:50](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedValue.ts#L50) A high-level Solid hook that creates a rate-limited version of a value that updates at most a certain number of times within a time window. This hook uses Solid's createSignal internally to manage the rate-limited state. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - createThrottledValue: When you want consistent spacing between updates (e.g. UI changes) - createDebouncedValue: When you want to collapse rapid updates into a single update (e.g. search input) @@ -56,10 +62,11 @@ consider using the lower-level createRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update at most 5 times per minute +// Basic rate limiting - update at most 5 times per minute with a sliding window const [rateLimitedValue, rateLimiter] = createRateLimitedValue(rawValue, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); // Use the rate-limited value diff --git a/docs/ru/framework/solid/reference/functions/createratelimiter.md b/docs/ru/framework/solid/reference/functions/createratelimiter.md index 655f82436..b1306bed8 100644 --- a/docs/ru/framework/solid/reference/functions/createratelimiter.md +++ b/docs/ru/framework/solid/reference/functions/createratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:17:21.164Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:59:36.057Z' id: createRateLimiter title: createRateLimiter --- @@ -13,7 +13,7 @@ title: createRateLimiter function createRateLimiter(fn, initialOptions): SolidRateLimiter ``` -Defined in: [rate-limiter/createRateLimiter.ts:61](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts#L61) +Defined in: [rate-limiter/createRateLimiter.ts:68](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts#L68) A low-level Solid hook that creates a `RateLimiter` instance to enforce rate limits on function execution. @@ -24,6 +24,12 @@ Rate limiting is a simple "hard limit" approach that allows executions until a m a time window, then blocks all subsequent calls until the window resets. Unlike throttling or debouncing, it does not attempt to space out or collapse executions intelligently. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns: - Use throttling when you want consistent spacing between executions (e.g. UI updates) - Use debouncing when you want to collapse rapid-fire events (e.g. search input) @@ -50,10 +56,11 @@ For smoother execution patterns: ## Example ```tsx -// Basic rate limiting - max 5 calls per minute +// Basic rate limiting - max 5 calls per minute with a sliding window const rateLimiter = createRateLimiter(apiCall, { limit: 5, window: 60000, + windowType: 'sliding' }); // Monitor rate limit status diff --git a/docs/ru/guides/debouncing.md b/docs/ru/guides/debouncing.md index cfc5097ed..e2cf5bab0 100644 --- a/docs/ru/guides/debouncing.md +++ b/docs/ru/guides/debouncing.md @@ -1,16 +1,16 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:19:56.587Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:02:11.996Z' title: Руководство по дебаунсингу id: debouncing --- # Руководство по Дебаунсингу (Debouncing) -Rate Limiting (ограничение частоты), Throttling (троттлинг) и Debouncing (дебаунсинг) — это три различных подхода к контролю частоты выполнения функций. Каждая техника по-разному блокирует выполнение, делая их "потерянными" (lossy) — это означает, что некоторые вызовы функций не будут выполнены, если они запрашиваются слишком часто. Понимание того, когда использовать каждый подход, крайне важно для создания производительных и надежных приложений. В этом руководстве рассматриваются концепции дебаунсинга в TanStack Pacer. +Ограничение частоты (Rate Limiting), Троттлинг (Throttling) и Дебаунсинг (Debouncing) — это три различных подхода к управлению частотой выполнения функций. Каждая техника по-разному блокирует выполнение, делая их "потерянными" (lossy) — это означает, что некоторые вызовы функций не будут выполнены, если они запрашиваются слишком часто. Понимание, когда использовать каждый подход, критически важно для создания производительных и надежных приложений. В этом руководстве рассматриваются концепции Дебаунсинга в TanStack Pacer. ## Концепция Дебаунсинга (Debouncing) -Дебаунсинг — это техника, которая откладывает выполнение функции до тех пор, пока не пройдет указанный период бездействия. В отличие от ограничения частоты (rate limiting), которое допускает всплески вызовов до определенного предела, или троттлинга (throttling), который обеспечивает равномерное выполнение, дебаунсинг объединяет несколько быстрых вызовов функции в одно выполнение, которое происходит только после остановки вызовов. Это делает дебаунсинг идеальным для обработки всплесков событий, где важно только конечное состояние после завершения активности. +Дебаунсинг — это техника, которая откладывает выполнение функции до тех пор, пока не пройдет указанный период бездействия. В отличие от ограничения частоты (rate limiting), которое допускает всплески выполнения до определенного предела, или троттлинга (throttling), который обеспечивает равномерно распределенные выполнения, дебаунсинг объединяет несколько быстрых вызовов функции в одно выполнение, которое происходит только после остановки вызовов. Это делает дебаунсинг идеальным для обработки всплесков событий, где важно только конечное состояние после завершения активности. ### Визуализация Дебаунсинга @@ -23,44 +23,44 @@ Executed: ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ⏳ -> ✅ ❌ ^ Выполняется здесь после 3 тиков без вызовов - [Всплеск вызовов] [Еще вызовы] [Ожидание] [Новый всплеск] - Нет выполнения Сброс таймера [Отложенное выполнение] [Ожидание] [Отложенное выполнение] + [Всплеск вызовов] [Дополнительные вызовы] [Ожидание] [Новый всплеск] + Нет выполнения Сбрасывает таймер [Отложенное выполнение] [Ожидание] [Отложенное выполнение] ``` -### Когда Использовать Дебаунсинг +### Когда использовать Дебаунсинг -Дебаунсинг особенно эффективен, когда нужно дождаться "паузы" в активности перед выполнением действия. Это делает его идеальным для обработки пользовательского ввода или других быстро повторяющихся событий, где важно только конечное состояние. +Дебаунсинг особенно эффективен, когда вы хотите дождаться "паузы" в активности перед выполнением действия. Это делает его идеальным для обработки пользовательского ввода или других быстро повторяющихся событий, где важно только конечное состояние. Распространенные сценарии использования: -- Поля поиска, где нужно дождаться окончания ввода пользователем -- Валидация форм, которая не должна запускаться при каждом нажатии клавиши -- Расчеты при изменении размера окна, которые требуют больших вычислений +- Поля поиска, где нужно дождаться завершения ввода пользователем +- Валидация форм, которая не должна выполняться при каждом нажатии клавиши +- Вычисления при изменении размера окна, которые требуют значительных ресурсов - Автосохранение черновиков при редактировании контента - API-вызовы, которые должны выполняться только после завершения активности пользователя -- Любые сценарии, где важно только конечное значение после быстрых изменений +- Любой сценарий, где важно только конечное значение после быстрых изменений -### Когда Не Использовать Дебаунсинг +### Когда не следует использовать Дебаунсинг Дебаунсинг может быть не лучшим выбором, когда: -- Нужно гарантированное выполнение в течение определенного периода (используйте [троттлинг](../guides/throttling)) +- Нужно гарантированное выполнение в определенный период времени (используйте [троттлинг](../guides/throttling)) - Нельзя пропускать ни одного выполнения (используйте [очередь (queueing)](../guides/queueing)) ## Дебаунсинг в TanStack Pacer TanStack Pacer предоставляет как синхронный, так и асинхронный дебаунсинг через классы `Debouncer` и `AsyncDebouncer` соответственно (и соответствующие функции `debounce` и `asyncDebounce`). -### Базовое Использование с `debounce` +### Базовое использование с `debounce` Функция `debounce` — это самый простой способ добавить дебаунсинг к любой функции: ```ts import { debounce } from '@tanstack/pacer' -// Дебаунсинг поля поиска для ожидания окончания ввода +// Дебаунсинг поля поиска для ожидания завершения ввода пользователем const debouncedSearch = debounce( (searchTerm: string) => performSearch(searchTerm), { - wait: 500, // Ждать 500 мс после последнего нажатия + wait: 500, // Ждать 500 мс после последнего нажатия клавиши } ) @@ -69,7 +69,7 @@ searchInput.addEventListener('input', (e) => { }) ``` -### Продвинутое Использование с Классом `Debouncer` +### Расширенное использование с классом `Debouncer` Для большего контроля над поведением дебаунсинга можно использовать класс `Debouncer` напрямую: @@ -92,9 +92,9 @@ searchDebouncer.setOptions({ wait: 1000 }) // Увеличение времен searchDebouncer.cancel() ``` -### Выполнение на Начале и Конце +### Выполнение на переднем и заднем крае (Leading и Trailing) -Синхронный дебаунсер поддерживает выполнение как на начальном (leading), так и на конечном (trailing) этапе: +Синхронный дебаунсер поддерживает выполнение как на переднем (leading), так и на заднем (trailing) крае: ```ts const debouncedFn = debounce(fn, { @@ -111,14 +111,14 @@ const debouncedFn = debounce(fn, { Распространенные паттерны: - `{ leading: false, trailing: true }` — По умолчанию, выполнение после ожидания -- `{ leading: true, trailing: false }` — Выполнить сразу, игнорировать последующие вызовы -- `{ leading: true, trailing: true }` — Выполнить как при первом вызове, так и после ожидания +- `{ leading: true, trailing: false }` — Выполнение сразу, игнорирование последующих вызовов +- `{ leading: true, trailing: true }` — Выполнение как при первом вызове, так и после ожидания -### Максимальное Время Ожидания +### Максимальное время ожидания (Max Wait Time) -Дебаунсер TanStack Pacer намеренно НЕ имеет опции `maxWait`, в отличие от других библиотек дебаунсинга. Если нужно, чтобы выполнение происходило в более распределенный период времени, рассмотрите использование техники [троттлинга](../guides/throttling). +Дебаунсер TanStack Pacer намеренно не имеет опции `maxWait`, в отличие от других библиотек дебаунсинга. Если нужно, чтобы выполнения происходили в более распределенный период времени, рассмотрите использование техники [троттлинга](../guides/throttling). -### Включение/Отключение +### Включение/отключение Класс `Debouncer` поддерживает включение/отключение через опцию `enabled`. Используя метод `setOptions`, можно включать/отключать дебаунсер в любое время: @@ -127,33 +127,33 @@ const debouncer = new Debouncer(fn, { wait: 500, enabled: false }) // Отклю debouncer.setOptions({ enabled: true }) // Включить в любое время ``` -Если используется адаптер для фреймворка, где параметры дебаунсера реактивны, можно установить опцию `enabled` в условное значение для динамического включения/отключения: +Если используется адаптер для фреймворка, где параметры дебаунсера реактивны, можно установить опцию `enabled` в условное значение для динамического включения/отключения дебаунсера: ```ts // Пример для React const debouncer = useDebouncer( setSearch, - { wait: 500, enabled: searchInput.value.length > 3 } // Включить/отключить в зависимости от длины ввода, ЕСЛИ используется адаптер фреймворка с поддержкой реактивных параметров + { wait: 500, enabled: searchInput.value.length > 3 } // Включение/отключение на основе длины ввода, ЕСЛИ используется адаптер фреймворка, поддерживающий реактивные параметры ) ``` -Однако при использовании функции `debounce` или класса `Debouncer` напрямую необходимо использовать метод `setOptions` для изменения опции `enabled`, так как переданные параметры фактически передаются в конструктор класса `Debouncer`. +Однако, если используется функция `debounce` или класс `Debouncer` напрямую, необходимо использовать метод `setOptions` для изменения опции `enabled`, так как передаваемые параметры фактически передаются в конструктор класса `Debouncer`. ```ts // Пример для Solid const debouncer = new Debouncer(fn, { wait: 500, enabled: false }) // Отключен по умолчанию createEffect(() => { - debouncer.setOptions({ enabled: search().length > 3 }) // Включить/отключить в зависимости от длины ввода + debouncer.setOptions({ enabled: search().length > 3 }) // Включение/отключение на основе длины ввода }) ``` -### Опции Колбэков +### Опции обратных вызовов (Callback Options) -Как синхронный, так и асинхронный дебаунсеры поддерживают опции колбэков для обработки различных аспектов жизненного цикла дебаунсинга: +Как синхронный, так и асинхронный дебаунсеры поддерживают опции обратных вызовов для обработки различных аспектов жизненного цикла дебаунсинга. -#### Колбэки Синхронного Дебаунсера +#### Обратные вызовы синхронного дебаунсера -Синхронный `Debouncer` поддерживает следующий колбэк: +Синхронный `Debouncer` поддерживает следующий обратный вызов: ```ts const debouncer = new Debouncer(fn, { @@ -165,11 +165,11 @@ const debouncer = new Debouncer(fn, { }) ``` -Колбэк `onExecute` вызывается после каждого успешного выполнения дебаунсированной функции, что полезно для отслеживания выполнений, обновления состояния UI или выполнения операций очистки. +Обратный вызов `onExecute` вызывается после каждого успешного выполнения дебаунсированной функции, что полезно для отслеживания выполнений, обновления состояния UI или выполнения операций очистки. -#### Колбэки Асинхронного Дебаунсера +#### Обратные вызовы асинхронного дебаунсера -Асинхронный `AsyncDebouncer` имеет другой набор колбэков по сравнению с синхронной версией. +Асинхронный `AsyncDebouncer` имеет другой набор обратных вызовов по сравнению с синхронной версией. ```ts const asyncDebouncer = new AsyncDebouncer(async (value) => { @@ -185,43 +185,37 @@ const asyncDebouncer = new AsyncDebouncer(async (value) => { console.log('Асинхронная функция завершена', debouncer.getSettledCount()) }, onError: (error) => { - // Вызывается при ошибке в асинхронной функции + // Вызывается, если асинхронная функция выбрасывает ошибку console.error('Асинхронная функция завершилась с ошибкой:', error) } }) ``` -Колбэк `onSuccess` вызывается после каждого успешного выполнения дебаунсированной функции, а `onError` — если асинхронная функция выбрасывает ошибку. Колбэк `onSettled` вызывается после каждой попытки выполнения, независимо от успеха или ошибки. Эти колбэки особенно полезны для отслеживания количества выполнений, обновления состояния UI, обработки ошибок, выполнения операций очистки и логирования метрик выполнения. +Обратный вызов `onSuccess` вызывается после каждого успешного выполнения дебаунсированной функции, а `onError` вызывается, если асинхронная функция выбрасывает ошибку. `onSettled` вызывается после каждой попытки выполнения, независимо от успеха или ошибки. Эти обратные вызовы особенно полезны для отслеживания количества выполнений, обновления состояния UI, обработки ошибок, выполнения операций очистки и логирования метрик выполнения. -### Асинхронный Дебаунсинг +### Асинхронный дебаунсинг -Асинхронный дебаунсер предоставляет мощный способ обработки асинхронных операций с дебаунсингом, предлагая несколько ключевых преимуществ по сравнению с синхронной версией. В то время как синхронный дебаунсер отлично подходит для событий UI и мгновенной обратной связи, асинхронная версия специально разработана для обработки API-вызовов, операций с базой данных и других асинхронных задач. +Асинхронный дебаунсер предоставляет мощный способ обработки асинхронных операций с дебаунсингом, предлагая несколько ключевых преимуществ по сравнению с синхронной версией. В то время как синхронный дебаунсер отлично подходит для событий UI и немедленной обратной связи, асинхронная версия специально разработана для обработки API-вызовов, операций с базой данных и других асинхронных задач. -#### Ключевые Отличия от Синхронного Дебаунсинга +#### Ключевые отличия от синхронного дебаунсинга -1. **Обработка Возвращаемого Значения** -В отличие от синхронного дебаунсера, который возвращает void, асинхронная версия позволяет захватывать и использовать возвращаемое значение из дебаунсированной функции. Это особенно полезно при работе с результатами API-вызовов или других асинхронных операций. Метод `maybeExecute` возвращает Promise, который разрешается с возвращаемым значением функции, позволяя ожидать результат и обрабатывать его соответствующим образом. +1. **Обработка возвращаемого значения** +В отличие от синхронного дебаунсера, который возвращает void, асинхронная версия позволяет захватывать и использовать возвращаемое значение из вашей дебаунсированной функции. Это особенно полезно, когда нужно работать с результатами API-вызовов или других асинхронных операций. Метод `maybeExecute` возвращает Promise, который разрешается с возвращаемым значением функции, позволяя ожидать результат и обрабатывать его соответствующим образом. -2. **Расширенная Система Колбэков** -Асинхронный дебаунсер предоставляет более сложную систему колбэков по сравнению с единственным колбэком `onExecute` в синхронной версии. Эта система включает: -- `onSuccess`: Вызывается при успешном завершении асинхронной функции, предоставляя как результат, так и экземпляр дебаунсера -- `onError`: Вызывается при ошибке в асинхронной функции, предоставляя как ошибку, так и экземпляр дебаунсера -- `onSettled`: Вызывается после каждой попытки выполнения, независимо от успеха или ошибки +2. **Разные обратные вызовы** +`AsyncDebouncer` поддерживает следующие обратные вызовы вместо только `onExecute` в синхронной версии: +- `onSuccess`: Вызывается после каждого успешного выполнения, предоставляя экземпляр дебаунсера +- `onSettled`: Вызывается после каждого выполнения, предоставляя экземпляр дебаунсера +- `onError`: Вызывается, если асинхронная функция выбрасывает ошибку, предоставляя как ошибку, так и экземпляр дебаунсера -3. **Отслеживание Выполнений** -Асинхронный дебаунсер предоставляет комплексное отслеживание выполнений через несколько методов: -- `getSuccessCount()`: Количество успешных выполнений -- `getErrorCount()`: Количество неудачных выполнений -- `getSettledCount()`: Общее количество завершенных выполнений (успешные + неудачные) +3. **Последовательное выполнение** +Поскольку метод `maybeExecute` дебаунсера возвращает Promise, можно ожидать каждое выполнение перед началом следующего. Это дает контроль над порядком выполнения и гарантирует, что каждый вызов обрабатывает самые актуальные данные. Это особенно полезно при работе с операциями, которые зависят от результатов предыдущих вызовов, или когда критически важна согласованность данных. -4. **Последовательное Выполнение** -Асинхронный дебаунсер гарантирует, что последующие выполнения ждут завершения предыдущего вызова перед началом. Это предотвращает выполнение в неправильном порядке и гарантирует, что каждый вызов обрабатывает самые актуальные данные. Это особенно важно при работе с операциями, которые зависят от результатов предыдущих вызовов, или когда критически важна согласованность данных. +Например, если обновляется профиль пользователя и затем сразу же запрашиваются обновленные данные, можно ожидать операцию обновления перед началом запроса: -Например, если обновляется профиль пользователя и затем сразу же запрашиваются обновленные данные, асинхронный дебаунсер гарантирует, что операция запроса дождется завершения обновления, предотвращая состояния гонки (race conditions), при которых можно получить устаревшие данные. +#### Базовый пример использования -#### Пример Базового Использования - -Вот базовый пример использования асинхронного дебаунсера для операции поиска: +Вот базовый пример, показывающий, как использовать асинхронный дебаунсер для операции поиска: ```ts const debouncedSearch = asyncDebounce( @@ -244,20 +238,7 @@ const debouncedSearch = asyncDebounce( const results = await debouncedSearch('query') ``` -#### Продвинутые Паттерны - -Асинхронный дебаунсер можно комбинировать с различными паттернами для решения сложных задач: - -1. **Интеграция с Управлением Состоянием** -При использовании асинхронного дебаунсера с системами управления состоянием (например, useState в React или createSignal в Solid) можно создавать мощные паттерны для обработки состояний загрузки, ошибок и обновления данных. Колбэки дебаунсера предоставляют идеальные хуки для обновления состояния UI на основе успеха или ошибки операций. - -2. **Предотвращение Состояний Гонки** -Паттерн единичной мутации (single-flight mutation) естественным образом предотвращает состояния гонки во многих сценариях. Когда несколько частей приложения пытаются одновременно обновить один и тот же ресурс, дебаунсер гарантирует, что выполнится только самое последнее обновление, при этом предоставляя результаты всем вызывающим сторонам. - -3. **Восстановление после Ошибок** -Возможности обработки ошибок асинхронного дебаунсера делают его идеальным для реализации логики повторных попыток и восстановления после ошибок. Можно использовать колбэк `onError` для реализации пользовательских стратегий обработки ошибок, таких как экспоненциальная задержка (exponential backoff) или механизмы отката (fallback). - -### Адаптеры для Фреймворков +### Адаптеры для фреймворков Каждый адаптер для фреймворка предоставляет хуки, которые расширяют базовую функциональность дебаунсинга для интеграции с системой управления состоянием фреймворка. Для каждого фреймворка доступны хуки, такие как `createDebouncer`, `useDebouncedCallback`, `useDebouncedState` или `useDebouncedValue`. @@ -274,7 +255,7 @@ const debouncer = useDebouncer( { wait: 500 } ) -// Простой хук для базовых сценариев +// Простой хук обратного вызова для базовых сценариев const handleSearch = useDebouncedCallback( (query: string) => fetchSearchResults(query), { wait: 500 } @@ -299,7 +280,7 @@ const debouncer = createDebouncer( { wait: 500 } ) -// Хук на основе сигналов для управления состоянием +// Хук на основе сигнала для управления состоянием const [searchTerm, setSearchTerm, debouncer] = createDebouncedSignal('', { wait: 500, onExecute: (debouncer) => { diff --git a/docs/ru/guides/rate-limiting.md b/docs/ru/guides/rate-limiting.md index db24aeefd..acbafff34 100644 --- a/docs/ru/guides/rate-limiting.md +++ b/docs/ru/guides/rate-limiting.md @@ -1,19 +1,19 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:19:56.788Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:02:32.139Z' title: Руководство по ограничению частоты id: rate-limiting --- # Руководство по ограничению частоты запросов (Rate Limiting) -Ограничение частоты запросов (Rate Limiting), регулирование (Throttling) и устранение дребезга (Debouncing) — это три различных подхода к контролю частоты выполнения функций. Каждая методика блокирует выполнение по-своему, делая их "потерянными" (lossy) — это означает, что некоторые вызовы функций не будут выполнены, если они запрашиваются слишком часто. Понимание, когда использовать каждый подход, критически важно для создания производительных и надежных приложений. В этом руководстве рассматриваются концепции ограничения частоты запросов в TanStack Pacer. +Ограничение частоты запросов (Rate Limiting), регулирование (Throttling) и устранение дребезга (Debouncing) — это три различных подхода к контролю частоты выполнения функций. Каждый метод по-разному блокирует выполнение, делая их "потерянными" (lossy) — это означает, что некоторые вызовы функций не будут выполнены, если они запрашиваются слишком часто. Понимание, когда использовать каждый подход, крайне важно для создания производительных и надежных приложений. В этом руководстве рассматриваются концепции ограничения частоты запросов в TanStack Pacer. > [!NOTE] -> TanStack Pacer в настоящее время является только фронтенд-библиотекой. Это утилиты для ограничения частоты запросов на стороне клиента. +> TanStack Pacer в настоящее время является библиотекой только для фронтенда. Это утилиты для ограничения частоты запросов на стороне клиента. -## Концепция ограничения частоты запросов +## Концепция ограничения частоты запросов (Rate Limiting) -Ограничение частоты запросов (Rate Limiting) — это методика, которая ограничивает частоту выполнения функции в определенном временном окне. Она особенно полезна в сценариях, когда нужно предотвратить слишком частые вызовы функции, например, при обработке API-запросов или других вызовов внешних сервисов. Это наиболее *наивный* подход, так как он позволяет выполнять вызовы пакетами до исчерпания квоты. +Ограничение частоты запросов (Rate Limiting) — это метод, который ограничивает частоту выполнения функции в течение определенного временного окна. Он особенно полезен в сценариях, где нужно предотвратить слишком частые вызовы функции, например, при обработке API-запросов или других вызовов внешних сервисов. Это наиболее *простой* подход, так как он позволяет выполнять вызовы пакетами до достижения квоты. ### Визуализация ограничения частоты запросов @@ -26,27 +26,56 @@ Executed: ✅ ✅ ✅ ❌ ❌ [=== 3 allowed ===][=== blocked until window ends ===][=== new window =======] ``` +### Типы окон + +TanStack Pacer поддерживает два типа окон для ограничения частоты запросов: + +1. **Фиксированное окно (Fixed Window)** (по умолчанию) + - Строгое окно, которое сбрасывается после завершения периода + - Все выполнения в пределах окна учитываются в лимите + - Окно полностью сбрасывается после периода + - Может приводить к пакетному поведению на границах окон + +2. **Скользящее окно (Sliding Window)** + - Динамическое окно, позволяющее выполнять вызовы по мере истечения старых + - Обеспечивает более равномерную частоту выполнения с течением времени + - Лучше подходит для поддержания стабильного потока выполнений + - Предотвращает пакетное поведение на границах окон + +Вот визуализация ограничения частоты запросов со скользящим окном: + +```text +Sliding Window Rate Limiting (limit: 3 calls per window) +Timeline: [1 second per tick] + Window 1 | Window 2 +Calls: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ +Executed: ✅ ✅ ✅ ❌ ✅ ✅ ✅ + [=== 3 allowed ===][=== oldest expires, new allowed ===][=== continues sliding =======] +``` + +Ключевое отличие заключается в том, что при скользящем окне, как только истекает срок самого старого выполнения, разрешается новое выполнение. Это создает более равномерный поток выполнений по сравнению с подходом фиксированного окна. + ### Когда использовать ограничение частоты запросов Ограничение частоты запросов особенно важно при работе с фронтенд-операциями, которые могут случайно перегрузить бэкенд-сервисы или вызвать проблемы с производительностью в браузере. Распространенные сценарии использования: - Предотвращение случайного спама API из-за быстрых действий пользователя (например, кликов по кнопке или отправки форм) -- Сценарии, где допустимо пакетное поведение, но нужно ограничить максимальную частоту +- Сценарии, где пакетное поведение допустимо, но требуется ограничить максимальную частоту - Защита от случайных бесконечных циклов или рекурсивных операций -### Когда не следует использовать ограничение частоты запросов +### Когда не использовать ограничение частоты запросов -Ограничение частоты запросов — это наиболее наивный подход к контролю частоты выполнения функций. Он наименее гибкий и наиболее ограничительный среди трех методик. Рассмотрите использование [регулирования (throttling)](../guides/throttling) или [устранения дребезга (debouncing)](../guides/debouncing) для более равномерного распределения выполнения. +Ограничение частоты запросов — это самый простой подход к контролю частоты выполнения функций. Он наименее гибкий и наиболее ограничительный из трех методов. Вместо него рассмотрите использование [регулирования (throttling)](../guides/throttling) или [устранения дребезга (debouncing)](../guides/debouncing) для более равномерного выполнения. > [!TIP] -> В большинстве случаев вам, скорее всего, не нужно использовать "ограничение частоты запросов". Рассмотрите использование [регулирования (throttling)](../guides/throttling) или [устранения дребезга (debouncing)](../guides/debouncing) вместо этого. +> В большинстве случаев вам, скорее всего, не нужно использовать "ограничение частоты запросов". Вместо этого рассмотрите [регулирование (throttling)](../guides/throttling) или [устранение дребезга (debouncing)](../guides/debouncing). -"Потерянная" природа ограничения частоты запросов также означает, что некоторые выполнения будут отклонены и потеряны. Это может быть проблемой, если нужно гарантировать успешность всех выполнений. Рассмотрите использование [очереди (queueing)](../guides/queueing), если необходимо обеспечить, чтобы все выполнения были поставлены в очередь для выполнения, но с задержкой для замедления частоты выполнения. +"Потерянная" природа ограничения частоты запросов также означает, что некоторые выполнения будут отклонены и потеряны. Это может быть проблемой, если нужно гарантировать, что все выполнения всегда успешны. Рассмотрите использование [очереди (queueing)](../guides/queueing), если требуется обеспечить, чтобы все выполнения были поставлены в очередь для выполнения, но с задержкой для замедления частоты выполнения. ## Ограничение частоты запросов в TanStack Pacer -TanStack Pacer предоставляет как синхронное, так и асинхронное ограничение частоты запросов через классы `RateLimiter` и `AsyncRateLimiter` соответственно (и соответствующие функции `rateLimit` и `asyncRateLimit`). +TanStack Pacer предоставляет синхронное и асинхронное ограничение частоты запросов через классы `RateLimiter` и `AsyncRateLimiter` соответственно (и соответствующие функции `rateLimit` и `asyncRateLimit`). ### Базовое использование с `rateLimit` @@ -61,6 +90,7 @@ const rateLimitedApi = rateLimit( { limit: 5, window: 60 * 1000, // 1 минута в миллисекундах + windowType: 'fixed', // по умолчанию onReject: (rateLimiter) => { console.log(`Превышен лимит запросов. Попробуйте снова через ${rateLimiter.getMsUntilNextWindow()}мс`) } @@ -76,14 +106,14 @@ rateLimitedApi('user-5') // ✅ Выполняется rateLimitedApi('user-6') // ❌ Отклоняется до сброса окна ``` -### Продвинутое использование с классом `RateLimiter` +### Расширенное использование с классом `RateLimiter` Для более сложных сценариев, где требуется дополнительный контроль над поведением ограничения частоты запросов, можно использовать класс `RateLimiter` напрямую. Это дает доступ к дополнительным методам и информации о состоянии. ```ts import { RateLimiter } from '@tanstack/pacer' -// Создание экземпляра ограничителя частоты запросов +// Создание экземпляра ограничителя const limiter = new RateLimiter( (id: string) => fetchUserData(id), { @@ -115,7 +145,10 @@ limiter.reset() ### Включение/отключение -Класс `RateLimiter` поддерживает включение/отключение через параметр `enabled`. Используя метод `setOptions`, можно включать/отключать ограничитель частоты запросов в любое время: +Класс `RateLimiter` поддерживает включение/отключение через опцию `enabled`. Используя метод `setOptions`, можно включать/отключать ограничитель в любое время: + +> [!NOTE] +> Опция `enabled` включает/отключает фактическое выполнение функции. Отключение ограничителя частоты запросов не отключает сам механизм ограничения, а только предотвращает выполнение функции. ```ts const limiter = new RateLimiter(fn, { @@ -126,13 +159,13 @@ const limiter = new RateLimiter(fn, { limiter.setOptions({ enabled: true }) // Включить в любое время ``` -Если используется адаптер для фреймворка, где параметры ограничителя реактивны, можно установить параметр `enabled` в условное значение для динамического включения/отключения ограничителя. Однако при использовании функции `rateLimit` или класса `RateLimiter` напрямую необходимо использовать метод `setOptions` для изменения параметра `enabled`, так как передаваемые параметры фактически передаются в конструктор класса `RateLimiter`. +Если используется адаптер для фреймворка, где параметры ограничителя реактивны, можно установить опцию `enabled` в условное значение для динамического включения/отключения ограничителя. Однако при использовании функции `rateLimit` или класса `RateLimiter` напрямую необходимо использовать метод `setOptions` для изменения опции `enabled`, так как переданные параметры фактически передаются в конструктор класса `RateLimiter`. -### Параметры обратных вызовов +### Опции обратных вызовов -Как синхронные, так и асинхронные ограничители частоты запросов поддерживают параметры обратных вызовов для обработки различных аспектов жизненного цикла ограничения частоты запросов: +Как синхронные, так и асинхронные ограничители поддерживают опции обратных вызовов для обработки различных аспектов жизненного цикла ограничения частоты запросов: -#### Обратные вызовы синхронного ограничителя частоты запросов +#### Обратные вызовы синхронного ограничителя Синхронный `RateLimiter` поддерживает следующие обратные вызовы: @@ -153,7 +186,7 @@ const limiter = new RateLimiter(fn, { Обратный вызов `onExecute` вызывается после каждого успешного выполнения ограниченной функции, а `onReject` — при отклонении выполнения из-за ограничения частоты запросов. Эти обратные вызовы полезны для отслеживания выполнений, обновления состояния UI или предоставления обратной связи пользователям. -#### Обратные вызовы асинхронного ограничителя частоты запросов +#### Обратные вызовы асинхронного ограничителя Асинхронный `AsyncRateLimiter` поддерживает дополнительные обратные вызовы для обработки ошибок: @@ -172,44 +205,39 @@ const asyncLimiter = new AsyncRateLimiter(async (id) => { console.log(`Превышен лимит запросов. Попробуйте снова через ${rateLimiter.getMsUntilNextWindow()}мс`) }, onError: (error) => { - // Вызывается при возникновении ошибки в асинхронной функции - console.error('Ошибка асинхронной функции:', error) + // Вызывается, если асинхронная функция выбрасывает ошибку + console.error('Асинхронная функция завершилась ошибкой:', error) } }) ``` -Обратные вызовы `onExecute` и `onReject` работают так же, как и в синхронном ограничителе, а `onError` позволяет обрабатывать ошибки без прерывания цепочки ограничения частоты запросов. Эти обратные вызовы особенно полезны для отслеживания количества выполнений, обновления состояния UI, обработки ошибок и предоставления обратной связи пользователям. +Обратные вызовы `onExecute` и `onReject` работают так же, как в синхронном ограничителе, а `onError` позволяет обрабатывать ошибки без прерывания цепочки ограничения частоты запросов. Эти обратные вызовы особенно полезны для отслеживания количества выполнений, обновления состояния UI, обработки ошибок и предоставления обратной связи пользователям. ### Асинхронное ограничение частоты запросов -Асинхронный ограничитель частоты запросов предоставляет мощный способ обработки асинхронных операций с ограничением частоты, предлагая несколько ключевых преимуществ по сравнению с синхронной версией. В то время как синхронный ограничитель отлично подходит для событий UI и немедленной обратной связи, асинхронная версия специально разработана для обработки API-вызовов, операций с базой данных и других асинхронных задач. +Асинхронный ограничитель предоставляет мощный способ обработки асинхронных операций с ограничением частоты запросов, предлагая несколько ключевых преимуществ по сравнению с синхронной версией. В то время как синхронный ограничитель отлично подходит для событий UI и немедленной обратной связи, асинхронная версия специально разработана для обработки API-вызовов, операций с базой данных и других асинхронных задач. #### Ключевые отличия от синхронного ограничения частоты запросов -1. **Обработка возвращаемых значений** +1. **Обработка возвращаемого значения** В отличие от синхронного ограничителя, который возвращает boolean, указывающий на успех, асинхронная версия позволяет захватывать и использовать возвращаемое значение из ограниченной функции. Это особенно полезно при работе с результатами API-вызовов или других асинхронных операций. Метод `maybeExecute` возвращает Promise, который разрешается с возвращаемым значением функции, позволяя ожидать результат и обрабатывать его соответствующим образом. -2. **Улучшенная система обратных вызовов** -Асинхронный ограничитель частоты запросов предоставляет более сложную систему обратных вызовов по сравнению с синхронной версией. Эта система включает: -- `onExecute`: Вызывается после каждого успешного выполнения, предоставляя экземпляр ограничителя -- `onReject`: Вызывается при отклонении выполнения из-за ограничения частоты запросов, предоставляя экземпляр ограничителя -- `onError`: Вызывается при возникновении ошибки в асинхронной функции, предоставляя как ошибку, так и экземпляр ограничителя +2. **Разные обратные вызовы** +`AsyncRateLimiter` поддерживает следующие обратные вызовы вместо только `onExecute` в синхронной версии: +- `onSuccess`: Вызывается после каждого успешного выполнения, предоставляя экземпляр ограничителя +- `onSettled`: Вызывается после каждого выполнения, предоставляя экземпляр ограничителя +- `onError`: Вызывается, если асинхронная функция выбрасывает ошибку, предоставляя как ошибку, так и экземпляр ограничителя -3. **Отслеживание выполнений** -Асинхронный ограничитель частоты запросов предоставляет комплексное отслеживание выполнений через несколько методов: -- `getExecutionCount()`: Количество успешных выполнений -- `getRejectionCount()`: Количество отклоненных выполнений -- `getRemainingInWindow()`: Количество оставшихся выполнений в текущем окне -- `getMsUntilNextWindow()`: Миллисекунды до начала следующего окна +Как асинхронные, так и синхронные ограничители поддерживают обратный вызов `onReject` для обработки заблокированных выполнений. -4. **Последовательное выполнение** -Асинхронный ограничитель частоты запросов гарантирует, что последующие выполнения ждут завершения предыдущего вызова перед началом. Это предотвращает выполнение в неправильном порядке и гарантирует, что каждый вызов обрабатывает самые актуальные данные. Это особенно важно при работе с операциями, которые зависят от результатов предыдущих вызовов, или когда критически важна согласованность данных. +3. **Последовательное выполнение** +Поскольку метод `maybeExecute` ограничителя возвращает Promise, можно ожидать каждое выполнение перед началом следующего. Это дает контроль над порядком выполнения и гарантирует, что каждый вызов обрабатывает самые актуальные данные. Это особенно полезно при работе с операциями, которые зависят от результатов предыдущих вызовов, или когда критически важна согласованность данных. -Например, если вы обновляете профиль пользователя и затем сразу же получаете обновленные данные, асинхронный ограничитель частоты запросов гарантирует, что операция получения ждет завершения обновления, предотвращая состояния гонки, когда могут быть получены устаревшие данные. +Например, если обновляется профиль пользователя и затем сразу же запрашиваются обновленные данные, можно ожидать операцию обновления перед началом запроса: #### Пример базового использования -Вот базовый пример использования асинхронного ограничителя частоты запросов для API-операции: +Вот простой пример использования асинхронного ограничителя для API-операции: ```ts const rateLimitedApi = asyncRateLimit( @@ -227,7 +255,7 @@ const rateLimitedApi = asyncRateLimit( console.log(`Превышен лимит запросов. Попробуйте снова через ${limiter.getMsUntilNextWindow()}мс`) }, onError: (error, limiter) => { - console.error('Ошибка API-вызова:', error) + console.error('API-вызов завершился ошибкой:', error) } } ) @@ -236,19 +264,6 @@ const rateLimitedApi = asyncRateLimit( const result = await rateLimitedApi('123') ``` -#### Продвинутые паттерны - -Асинхронный ограничитель частоты запросов можно комбинировать с различными паттернами для решения сложных задач: - -1. **Интеграция с управлением состоянием** -При использовании асинхронного ограничителя с системами управления состоянием (такими как useState в React или createSignal в Solid) можно создавать мощные паттерны для обработки состояний загрузки, ошибок и обновления данных. Обратные вызовы ограничителя предоставляют идеальные хуки для обновления состояния UI на основе успеха или неудачи операций. - -2. **Предотвращение состояний гонки** -Паттерн ограничения частоты запросов естественным образом предотвращает состояния гонки во многих сценариях. Когда несколько частей приложения пытаются обновить один и тот же ресурс одновременно, ограничитель гарантирует, что обновления происходят в пределах настроенных лимитов, при этом все еще предоставляя результаты всем вызывающим сторонам. - -3. **Восстановление после ошибок** -Возможности обработки ошибок асинхронного ограничителя делают его идеальным для реализации логики повторных попыток и паттернов восстановления после ошибок. Можно использовать обратный вызов `onError` для реализации пользовательских стратегий обработки ошибок, таких как экспоненциальная задержка или механизмы резервного копирования. - ### Адаптеры для фреймворков Каждый адаптер для фреймворка предоставляет хуки, которые расширяют базовую функциональность ограничения частоты запросов для интеграции с системой управления состоянием фреймворка. Для каждого фреймворка доступны хуки, такие как `createRateLimiter`, `useRateLimitedCallback`, `useRateLimitedState` или `useRateLimitedValue`. @@ -275,7 +290,7 @@ const handleFetch = useRateLimitedCallback( // Хук на основе состояния для реактивного управления состоянием const [instantState, setInstantState] = useState('') const [rateLimitedValue] = useRateLimitedValue( - instantState, // Значение для ограничения частоты запросов + instantState, // Значение для ограничения частоты { limit: 5, window: 1000 } ) ``` @@ -289,3 +304,9 @@ import { createRateLimiter, createRateLimitedSignal } from '@tanstack/solid-pace const limiter = createRateLimiter( (id: string) => fetchUserData(id), { limit: 5, window: 1000 } +) + +// Хук на основе сигнала для управления состоянием +const [value, setValue, limiter] = createRateLimitedSignal('', { + limit: 5, + window: diff --git a/docs/ru/guides/throttling.md b/docs/ru/guides/throttling.md index bf0117256..bb0f0f742 100644 --- a/docs/ru/guides/throttling.md +++ b/docs/ru/guides/throttling.md @@ -1,59 +1,59 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:19:51.589Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T06:02:10.702Z' title: Руководство по троттлингу id: throttling --- -# Руководство по троттлингу (Throttling) +# Руководство по троттлингу (Throttling Guide) -Ограничение частоты (Rate Limiting), троттлинг (Throttling) и дебаунсинг (Debouncing) — это три различных подхода к управлению частотой выполнения функций. Каждый метод по-разному блокирует выполнение, делая их "потерянными" (lossy) — это означает, что некоторые вызовы функций не будут выполнены, если они запрашиваются слишком часто. Понимание, когда использовать каждый подход, крайне важно для создания производительных и надежных приложений. В этом руководстве рассматриваются концепции троттлинга в TanStack Pacer. +Ограничение частоты (Rate Limiting), троттлинг (Throttling) и дебаунсинг (Debouncing) — это три различных подхода к контролю частоты выполнения функций. Каждый метод по-своему блокирует выполнение, делая их "потерянными" (lossy) — это означает, что некоторые вызовы функций не будут выполнены, если они запрашиваются слишком часто. Понимание, когда использовать каждый подход, крайне важно для создания производительных и надежных приложений. В этом руководстве рассматриваются концепции троттлинга в TanStack Pacer. -## Концепция троттлинга (Throttling) +## Концепция троттлинга (Throttling Concept) -Троттлинг гарантирует равномерное распределение выполнения функций во времени. В отличие от ограничения частоты (rate limiting), которое допускает всплески выполнения до определенного предела, или дебаунсинга (debouncing), который ждет прекращения активности, троттлинг создает более плавный паттерн выполнения, устанавливая постоянные задержки между вызовами. Если вы установите троттлинг на одно выполнение в секунду, вызовы будут равномерно распределены, независимо от того, как часто они запрашиваются. +Троттлинг гарантирует, что выполнение функций равномерно распределено во времени. В отличие от ограничения частоты (rate limiting), которое допускает всплески выполнения до определенного предела, или дебаунсинга (debouncing), который ждет остановки активности, троттлинг создает более плавный паттерн выполнения, обеспечивая постоянные задержки между вызовами. Если вы установите троттлинг на одно выполнение в секунду, вызовы будут равномерно распределены, независимо от того, как часто они запрашиваются. -### Визуализация троттлинга +### Визуализация троттлинга (Throttling Visualization) ```text -Троттлинг (одно выполнение за 3 тика) -Таймлайн: [1 секунда на тик] -Вызовы: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ -Выполнено: ✅ ❌ ⏳ -> ✅ ❌ ❌ ❌ ✅ ✅ +Throttling (one execution per 3 ticks) +Timeline: [1 second per tick] +Calls: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ +Executed: ✅ ❌ ⏳ -> ✅ ❌ ❌ ❌ ✅ ✅ [=================================================================] - ^ Разрешено только одно выполнение за 3 тика, - независимо от количества вызовов + ^ Only one execution allowed per 3 ticks, + regardless of how many calls are made - [Первый всплеск] [Дополнительные вызовы] [Равномерные вызовы] - Выполнить первый Выполнить после Выполнять каждый раз, - затем троттлинг периода ожидания когда проходит период ожидания + [First burst] [More calls] [Spaced calls] + Execute first Execute after Execute each time + then throttle wait period wait period passes ``` -### Когда использовать троттлинг +### Когда использовать троттлинг (When to Use Throttling) -Троттлинг особенно эффективен, когда вам нужно постоянное, предсказуемое время выполнения. Это делает его идеальным для обработки частых событий или обновлений, где требуется плавное, контролируемое поведение. +Троттлинг особенно эффективен, когда вам нужно последовательное, предсказуемое время выполнения. Это делает его идеальным для обработки частых событий или обновлений, где требуется плавное, контролируемое поведение. -Типичные сценарии использования: -- Обновления пользовательского интерфейса (UI), требующие постоянного времени (например, индикаторы прогресса) +Распространенные сценарии использования: +- Обновления пользовательского интерфейса (UI updates), требующие стабильного времени (например, индикаторы прогресса) - Обработчики событий прокрутки (scroll) или изменения размера (resize), которые не должны перегружать браузер -- Опрос данных в реальном времени (real-time polling), где желательны постоянные интервалы -- Ресурсоемкие операции, требующие равномерного темпа -- Обновления игрового цикла (game loop) или обработка кадров анимации (animation frame) -- Живые подсказки поиска (live search) при вводе пользователем +- Опрос данных в реальном времени (real-time data polling), где требуются постоянные интервалы +- Ресурсоемкие операции (resource-intensive operations), требующие равномерного темпа +- Обновления игрового цикла (game loop updates) или обработка кадров анимации (animation frame handling) +- Подсказки при поиске в реальном времени (live search suggestions) по мере ввода пользователем -### Когда не использовать троттлинг +### Когда не использовать троттлинг (When Not to Use Throttling) Троттлинг может быть не лучшим выбором, когда: -- Нужно дождаться прекращения активности (используйте [дебаунсинг](../guides/debouncing)) -- Нельзя пропускать ни одного выполнения (используйте [очередь (queueing)](../guides/queueing)) +- Вы хотите дождаться остановки активности (вместо этого используйте [дебаунсинг](../guides/debouncing)) +- Вы не можете позволить себе пропустить ни одного выполнения (вместо этого используйте [очередь (queueing)](../guides/queueing)) > [!TIP] -> Троттлинг часто является лучшим выбором, когда требуется плавное, постоянное время выполнения. Он обеспечивает более предсказуемый паттерн выполнения, чем ограничение частоты (rate limiting), и более быструю обратную связь, чем дебаунсинг (debouncing). +> Троттлинг часто является лучшим выбором, когда вам нужно плавное, последовательное время выполнения. Он обеспечивает более предсказуемый паттерн выполнения, чем ограничение частоты (rate limiting), и более быструю обратную связь, чем дебаунсинг (debouncing). -## Троттлинг в TanStack Pacer +## Троттлинг в TanStack Pacer (Throttling in TanStack Pacer) -TanStack Pacer предоставляет синхронный и асинхронный троттлинг через классы `Throttler` и `AsyncThrottler` соответственно (и соответствующие функции `throttle` и `asyncThrottle`). +TanStack Pacer предоставляет как синхронный, так и асинхронный троттлинг через классы `Throttler` и `AsyncThrottler` соответственно (и соответствующие функции `throttle` и `asyncThrottle`). -### Базовое использование с `throttle` +### Базовое использование с `throttle` (Basic Usage with `throttle`) Функция `throttle` — это самый простой способ добавить троттлинг к любой функции: @@ -74,7 +74,7 @@ for (let i = 0; i < 100; i++) { } ``` -### Продвинутое использование с классом `Throttler` +### Расширенное использование с классом `Throttler` (Advanced Usage with `Throttler` Class) Для большего контроля над поведением троттлинга можно напрямую использовать класс `Throttler`: @@ -94,9 +94,9 @@ console.log(updateThrottler.getLastExecutionTime()) // Время последн updateThrottler.cancel() ``` -### Первое и последнее выполнение +### Первое и последующее выполнение (Leading and Trailing Executions) -Синхронный троттлер поддерживает выполнение как по первому (leading), так и по последнему (trailing) вызову: +Синхронный троттлер поддерживает выполнение как на переднем (leading), так и на заднем (trailing) фронте: ```ts const throttledFn = throttle(fn, { @@ -106,32 +106,32 @@ const throttledFn = throttle(fn, { }) ``` -- `leading: true` (по умолчанию) — Выполнить сразу при первом вызове -- `leading: false` — Пропустить первый вызов, ждать последнего выполнения +- `leading: true` (по умолчанию) — Выполнить немедленно при первом вызове +- `leading: false` — Пропустить первый вызов, ждать последующего выполнения - `trailing: true` (по умолчанию) — Выполнить последний вызов после периода ожидания - `trailing: false` — Пропустить последний вызов, если он в пределах периода ожидания -Типичные паттерны: +Распространенные паттерны: - `{ leading: true, trailing: true }` — По умолчанию, наиболее отзывчивый - `{ leading: false, trailing: true }` — Задержать все выполнения -- `{ leading: true, trailing: false }` — Пропускать вызовы в очереди +- `{ leading: true, trailing: false }` — Пропустить вызовы в очереди -### Включение/отключение +### Включение/отключение (Enabling/Disabling) Класс `Throttler` поддерживает включение/отключение через опцию `enabled`. Используя метод `setOptions`, вы можете включать/отключать троттлер в любое время: ```ts -const throttler = new Throttler(fn, { wait: 200, enabled: false }) // Отключить по умолчанию +const throttler = new Throttler(fn, { wait: 200, enabled: false }) // Отключено по умолчанию throttler.setOptions({ enabled: true }) // Включить в любое время ``` Если вы используете адаптер для фреймворка, где параметры троттлера реактивны, вы можете установить опцию `enabled` в условное значение для динамического включения/отключения троттлера. Однако, если вы используете функцию `throttle` или класс `Throttler` напрямую, вы должны использовать метод `setOptions` для изменения опции `enabled`, так как переданные параметры фактически передаются в конструктор класса `Throttler`. -### Опции обратных вызовов (Callbacks) +### Опции обратного вызова (Callback Options) -Как синхронные, так и асинхронные троттлеры поддерживают опции обратных вызовов для обработки различных аспектов жизненного цикла троттлинга: +Как синхронный, так и асинхронный троттлеры поддерживают опции обратного вызова для обработки различных аспектов жизненного цикла троттлинга: -#### Обратные вызовы синхронного троттлера +#### Обратные вызовы синхронного троттлера (Synchronous Throttler Callbacks) Синхронный `Throttler` поддерживает следующий обратный вызов: @@ -145,9 +145,9 @@ const throttler = new Throttler(fn, { }) ``` -Обратный вызов `onExecute` вызывается после каждого успешного выполнения троттлируемой функции, что делает его полезным для отслеживания выполнений, обновления состояния UI или выполнения операций очистки. +Обратный вызов `onExecute` вызывается после каждого успешного выполнения троттлированной функции, что делает его полезным для отслеживания выполнений, обновления состояния UI или выполнения операций очистки. -#### Обратные вызовы асинхронного троттлера +#### Обратные вызовы асинхронного троттлера (Asynchronous Throttler Callbacks) Асинхронный `AsyncThrottler` поддерживает дополнительные обратные вызовы для обработки ошибок: @@ -169,35 +169,31 @@ const asyncThrottler = new AsyncThrottler(async (value) => { Обратный вызов `onExecute` работает так же, как и в синхронном троттлере, а `onError` позволяет обрабатывать ошибки без прерывания цепочки троттлинга. Эти обратные вызовы особенно полезны для отслеживания количества выполнений, обновления состояния UI, обработки ошибок, выполнения операций очистки и логирования метрик выполнения. -### Асинхронный троттлинг +### Асинхронный троттлинг (Asynchronous Throttling) -Асинхронный троттлер предоставляет мощный способ обработки асинхронных операций с троттлингом, предлагая несколько ключевых преимуществ перед синхронной версией. В то время как синхронный троттлер отлично подходит для событий UI и мгновенной обратной связи, асинхронная версия специально разработана для обработки вызовов API, операций с базой данных и других асинхронных задач. +Асинхронный троттлер предоставляет мощный способ обработки асинхронных операций с троттлингом, предлагая несколько ключевых преимуществ по сравнению с синхронной версией. В то время как синхронный троттлер отлично подходит для событий UI и мгновенной обратной связи, асинхронная версия специально разработана для обработки вызовов API, операций с базой данных и других асинхронных задач. -#### Ключевые отличия от синхронного троттлинга +#### Ключевые отличия от синхронного троттлинга (Key Differences from Synchronous Throttling) -1. **Обработка возвращаемого значения** -В отличие от синхронного троттлера, который возвращает void, асинхронная версия позволяет захватывать и использовать возвращаемое значение из вашей троттлируемой функции. Это особенно полезно, когда нужно работать с результатами вызовов API или других асинхронных операций. Метод `maybeExecute` возвращает Promise, который разрешается с возвращаемым значением функции, позволяя ожидать результат и обрабатывать его соответствующим образом. +1. **Обработка возвращаемого значения (Return Value Handling)** +В отличие от синхронного троттлера, который возвращает `void`, асинхронная версия позволяет захватывать и использовать возвращаемое значение из вашей троттлированной функции. Это особенно полезно, когда вам нужно работать с результатами вызовов API или других асинхронных операций. Метод `maybeExecute` возвращает Promise, который разрешается с возвращаемым значением функции, позволяя вам ожидать результат и обрабатывать его соответствующим образом. -2. **Улучшенная система обратных вызовов** -Асинхронный троттлер предоставляет более сложную систему обратных вызовов по сравнению с единственным `onExecute` в синхронной версии. Эта система включает: -- `onSuccess`: Вызывается при успешном завершении асинхронной функции, предоставляя как результат, так и экземпляр троттлера -- `onError`: Вызывается при ошибке в асинхронной функции, предоставляя как ошибку, так и экземпляр троттлера -- `onSettled`: Вызывается после каждой попытки выполнения, независимо от успеха или ошибки +2. **Разные обратные вызовы (Different Callbacks)** +`AsyncThrottler` поддерживает следующие обратные вызовы вместо только `onExecute` в синхронной версии: +- `onSuccess`: Вызывается после каждого успешного выполнения, предоставляя экземпляр троттлера +- `onSettled`: Вызывается после каждого выполнения, предоставляя экземпляр троттлера +- `onError`: Вызывается, если асинхронная функция выбрасывает ошибку, предоставляя как ошибку, так и экземпляр троттлера -3. **Отслеживание выполнения** -Асинхронный троттлер предоставляет комплексное отслеживание выполнения через несколько методов: -- `getSuccessCount()`: Количество успешных выполнений -- `getErrorCount()`: Количество неудачных выполнений -- `getSettledCount()`: Общее количество завершенных выполнений (успешные + ошибки) +Как асинхронный, так и синхронный троттлеры поддерживают обратный вызов `onExecute` для обработки успешных выполнений. -4. **Последовательное выполнение** -Асинхронный троттлер гарантирует, что последующие выполнения ждут завершения предыдущего вызова перед началом. Это предотвращает выполнение в неправильном порядке и гарантирует, что каждый вызов обрабатывает самые актуальные данные. Это особенно важно при работе с операциями, которые зависят от результатов предыдущих вызовов, или когда критически важна согласованность данных. +3. **Последовательное выполнение (Sequential Execution)** +Поскольку метод `maybeExecute` троттлера возвращает Promise, вы можете выбрать ожидание каждого выполнения перед началом следующего. Это дает вам контроль над порядком выполнения и гарантирует, что каждый вызов обрабатывает самые актуальные данные. Это особенно полезно при работе с операциями, зависящими от результатов предыдущих вызовов, или когда критически важна согласованность данных. -Например, если вы обновляете профиль пользователя и сразу же запрашиваете обновленные данные, асинхронный троттлер гарантирует, что операция запроса дождется завершения обновления, предотвращая состояния гонки (race conditions), при которых можно получить устаревшие данные. +Например, если вы обновляете профиль пользователя и затем сразу же получаете обновленные данные, вы можете ожидать завершения операции обновления перед началом получения: -#### Пример базового использования +#### Базовый пример использования (Basic Usage Example) -Вот простой пример использования асинхронного троттлера для операции поиска: +Вот базовый пример, показывающий, как использовать асинхронный троттлер для операции поиска: ```ts const throttledSearch = asyncThrottle( @@ -208,7 +204,7 @@ const throttledSearch = asyncThrottle( { wait: 500, onSuccess: (results, throttler) => { - console.log('Поиск успешен:', results) + console.log('Поиск выполнен успешно:', results) }, onError: (error, throttler) => { console.error('Поиск завершился ошибкой:', error) @@ -220,20 +216,7 @@ const throttledSearch = asyncThrottle( const results = await throttledSearch('query') ``` -#### Продвинутые паттерны - -Асинхронный троттлер можно комбинировать с различными паттернами для решения сложных задач: - -1. **Интеграция с управлением состоянием** -При использовании асинхронного троттлера с системами управления состоянием (такими как useState в React или createSignal в Solid) можно создавать мощные паттерны для обработки состояний загрузки, ошибок и обновления данных. Обратные вызовы троттлера предоставляют идеальные хуки для обновления состояния UI на основе успеха или неудачи операций. - -2. **Предотвращение состояний гонки** -Паттерн троттлинга естественным образом предотвращает состояния гонки во многих сценариях. Когда несколько частей вашего приложения пытаются одновременно обновить один и тот же ресурс, троттлер гарантирует, что обновления происходят с контролируемой скоростью, при этом предоставляя результаты всем вызывающим сторонам. - -3. **Восстановление после ошибок** -Возможности обработки ошибок асинхронного троттлера делают его идеальным для реализации логики повторных попыток и стратегий восстановления. Вы можете использовать обратный вызов `onError` для реализации пользовательских стратегий обработки ошибок, таких как экспоненциальная задержка (exponential backoff) или механизмы отката. - -### Адаптеры для фреймворков +### Адаптеры для фреймворков (Framework Adapters) Каждый адаптер для фреймворка предоставляет хуки, которые расширяют базовую функциональность троттлинга для интеграции с системой управления состоянием фреймворка. Для каждого фреймворка доступны хуки, такие как `createThrottler`, `useThrottledCallback`, `useThrottledState` или `useThrottledValue`. @@ -275,7 +258,7 @@ const throttler = createThrottler( { wait: 200 } ) -// Хук на основе сигналов (signals) для управления состоянием +// Хук на основе сигналов для управления состоянием const [value, setValue, throttler] = createThrottledSignal(0, { wait: 200, onExecute: (throttler) => { diff --git a/docs/ru/reference/classes/asyncdebouncer.md b/docs/ru/reference/classes/asyncdebouncer.md index 10c8d178d..2d743b199 100644 --- a/docs/ru/reference/classes/asyncdebouncer.md +++ b/docs/ru/reference/classes/asyncdebouncer.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:17:21.132Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:59:36.054Z' id: AsyncDebouncer title: AsyncDebouncer --- @@ -9,7 +9,7 @@ title: AsyncDebouncer # Class: AsyncDebouncer\ -Defined in: [async-debouncer.ts:73](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L73) +Defined in: [async-debouncer.ts:77](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L77) A class that creates an async debounced function. @@ -20,17 +20,21 @@ or input changes where you only want to execute the handler after the events hav Unlike throttling which allows execution at regular intervals, debouncing prevents any execution until the function stops being called for the specified delay period. +Unlike the non-async Debouncer, this async version supports returning values from the debounced function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the debounced function. + ## Example ```ts const asyncDebouncer = new AsyncDebouncer(async (value: string) => { - await searchAPI(value); + const results = await searchAPI(value); + return results; // Return value is preserved }, { wait: 500 }); // Called on each keystroke but only executes after 500ms of no typing -inputElement.addEventListener('input', () => { - asyncDebouncer.maybeExecute(inputElement.value); -}); +// Returns the API response directly +const results = await asyncDebouncer.maybeExecute(inputElement.value); ``` ## Type Parameters @@ -45,7 +49,7 @@ inputElement.addEventListener('input', () => { new AsyncDebouncer(fn, initialOptions): AsyncDebouncer ``` -Defined in: [async-debouncer.ts:86](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L86) +Defined in: [async-debouncer.ts:90](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L90) #### Parameters @@ -69,7 +73,7 @@ Defined in: [async-debouncer.ts:86](https://github.com/TanStack/pacer/blob/main/ cancel(): void ``` -Defined in: [async-debouncer.ts:195](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L195) +Defined in: [async-debouncer.ts:199](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L199) Cancels any pending execution or aborts any execution in progress @@ -85,7 +89,7 @@ Cancels any pending execution or aborts any execution in progress getErrorCount(): number ``` -Defined in: [async-debouncer.ts:224](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L224) +Defined in: [async-debouncer.ts:228](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L228) Returns the number of times the function has errored @@ -101,7 +105,7 @@ Returns the number of times the function has errored getIsExecuting(): boolean ``` -Defined in: [async-debouncer.ts:238](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L238) +Defined in: [async-debouncer.ts:242](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L242) Returns `true` if there is currently an execution in progress @@ -117,7 +121,7 @@ Returns `true` if there is currently an execution in progress getIsPending(): boolean ``` -Defined in: [async-debouncer.ts:231](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L231) +Defined in: [async-debouncer.ts:235](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L235) Returns `true` if there is a pending execution queued up for trailing execution @@ -133,7 +137,7 @@ Returns `true` if there is a pending execution queued up for trailing execution getLastResult(): undefined | ReturnType ``` -Defined in: [async-debouncer.ts:203](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L203) +Defined in: [async-debouncer.ts:207](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L207) Returns the last result of the debounced function @@ -149,7 +153,7 @@ Returns the last result of the debounced function getOptions(): Required> ``` -Defined in: [async-debouncer.ts:112](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L112) +Defined in: [async-debouncer.ts:116](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L116) Returns the current debouncer options @@ -165,7 +169,7 @@ Returns the current debouncer options getSettleCount(): number ``` -Defined in: [async-debouncer.ts:217](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L217) +Defined in: [async-debouncer.ts:221](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L221) Returns the number of times the function has settled (completed or errored) @@ -181,7 +185,7 @@ Returns the number of times the function has settled (completed or errored) getSuccessCount(): number ``` -Defined in: [async-debouncer.ts:210](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L210) +Defined in: [async-debouncer.ts:214](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L214) Returns the number of times the function has been executed successfully @@ -197,7 +201,7 @@ Returns the number of times the function has been executed successfully maybeExecute(...args): Promise> ``` -Defined in: [async-debouncer.ts:120](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L120) +Defined in: [async-debouncer.ts:124](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L124) Attempts to execute the debounced function If a call is already in progress, it will be queued @@ -220,7 +224,7 @@ If a call is already in progress, it will be queued setOptions(newOptions): void ``` -Defined in: [async-debouncer.ts:100](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L100) +Defined in: [async-debouncer.ts:104](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L104) Updates the debouncer options Returns the new options state diff --git a/docs/ru/reference/classes/asyncratelimiter.md b/docs/ru/reference/classes/asyncratelimiter.md index 6c750dbb3..7f35d5774 100644 --- a/docs/ru/reference/classes/asyncratelimiter.md +++ b/docs/ru/reference/classes/asyncratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:17:21.119Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:59:36.049Z' id: AsyncRateLimiter title: AsyncRateLimiter --- @@ -9,7 +9,7 @@ title: AsyncRateLimiter # Class: AsyncRateLimiter\ -Defined in: [async-rate-limiter.ts:76](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L76) +Defined in: [async-rate-limiter.ts:95](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L95) A class that creates an async rate-limited function. @@ -17,6 +17,16 @@ Rate limiting is a simple approach that allows a function to execute up to a lim then blocks all subsequent calls until the window passes. This can lead to "bursty" behavior where all executions happen immediately, followed by a complete block. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + +Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + For smoother execution patterns, consider using: - Throttling: Ensures consistent spacing between executions (e.g. max once per 200ms) - Debouncing: Waits for a pause in calls before executing (e.g. after 500ms of no calls) @@ -29,11 +39,12 @@ smoothing out frequent events, throttling or debouncing usually provide better u ```ts const rateLimiter = new AsyncRateLimiter( async (id: string) => await api.getData(id), - { limit: 5, window: 1000 } // 5 calls per second + { limit: 5, window: 1000, windowType: 'sliding' } // 5 calls per second with sliding window ); // Will execute immediately until limit reached, then block -await rateLimiter.maybeExecute('123'); +// Returns the API response directly +const data = await rateLimiter.maybeExecute('123'); ``` ## Type Parameters @@ -48,7 +59,7 @@ await rateLimiter.maybeExecute('123'); new AsyncRateLimiter(fn, initialOptions): AsyncRateLimiter ``` -Defined in: [async-rate-limiter.ts:85](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L85) +Defined in: [async-rate-limiter.ts:105](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L105) #### Parameters @@ -72,7 +83,7 @@ Defined in: [async-rate-limiter.ts:85](https://github.com/TanStack/pacer/blob/ma getErrorCount(): number ``` -Defined in: [async-rate-limiter.ts:209](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L209) +Defined in: [async-rate-limiter.ts:250](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L250) Returns the number of times the function has errored @@ -82,15 +93,33 @@ Returns the number of times the function has errored *** +### getIsExecuting() + +```ts +getIsExecuting(): boolean +``` + +Defined in: [async-rate-limiter.ts:264](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L264) + +Returns whether the function is currently executing + +#### Returns + +`boolean` + +*** + ### getMsUntilNextWindow() ```ts getMsUntilNextWindow(): number ``` -Defined in: [async-rate-limiter.ts:188](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L188) +Defined in: [async-rate-limiter.ts:225](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L225) Returns the number of milliseconds until the next execution will be possible +For fixed windows, this is the time until the current window resets +For sliding windows, this is the time until the oldest execution expires #### Returns @@ -104,7 +133,7 @@ Returns the number of milliseconds until the next execution will be possible getOptions(): Required> ``` -Defined in: [async-rate-limiter.ts:106](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L106) +Defined in: [async-rate-limiter.ts:126](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L126) Returns the current rate limiter options @@ -120,7 +149,7 @@ Returns the current rate limiter options getRejectionCount(): number ``` -Defined in: [async-rate-limiter.ts:216](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L216) +Defined in: [async-rate-limiter.ts:257](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L257) Returns the number of times the function has been rejected @@ -136,7 +165,7 @@ Returns the number of times the function has been rejected getRemainingInWindow(): number ``` -Defined in: [async-rate-limiter.ts:180](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L180) +Defined in: [async-rate-limiter.ts:215](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L215) Returns the number of remaining executions allowed in the current window @@ -152,7 +181,7 @@ Returns the number of remaining executions allowed in the current window getSettleCount(): number ``` -Defined in: [async-rate-limiter.ts:202](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L202) +Defined in: [async-rate-limiter.ts:243](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L243) Returns the number of times the function has been settled @@ -168,7 +197,7 @@ Returns the number of times the function has been settled getSuccessCount(): number ``` -Defined in: [async-rate-limiter.ts:195](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L195) +Defined in: [async-rate-limiter.ts:236](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L236) Returns the number of times the function has been executed @@ -184,7 +213,7 @@ Returns the number of times the function has been executed maybeExecute(...args): Promise> ``` -Defined in: [async-rate-limiter.ts:126](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L126) +Defined in: [async-rate-limiter.ts:146](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L146) Attempts to execute the rate-limited function if within the configured limits. Will reject execution if the number of calls in the current window exceeds the limit. @@ -220,7 +249,7 @@ await rateLimiter.maybeExecute('arg1', 'arg2'); // Rejected reset(): void ``` -Defined in: [async-rate-limiter.ts:223](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L223) +Defined in: [async-rate-limiter.ts:271](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L271) Resets the rate limiter state @@ -236,7 +265,7 @@ Resets the rate limiter state setOptions(newOptions): void ``` -Defined in: [async-rate-limiter.ts:99](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L99) +Defined in: [async-rate-limiter.ts:119](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L119) Updates the rate limiter options Returns the new options state diff --git a/docs/ru/reference/classes/asyncthrottler.md b/docs/ru/reference/classes/asyncthrottler.md index d23198868..0abb25f7a 100644 --- a/docs/ru/reference/classes/asyncthrottler.md +++ b/docs/ru/reference/classes/asyncthrottler.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:17:21.116Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:59:36.046Z' id: AsyncThrottler title: AsyncThrottler --- @@ -9,7 +9,7 @@ title: AsyncThrottler # Class: AsyncThrottler\ -Defined in: [async-throttler.ts:76](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L76) +Defined in: [async-throttler.ts:80](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L80) A class that creates an async throttled function. @@ -17,6 +17,10 @@ Throttling limits how often a function can be executed, allowing only one execut Unlike debouncing which resets the delay timer on each call, throttling ensures the function executes at a regular interval regardless of how often it's called. +Unlike the non-async Throttler, this async version supports returning values from the throttled function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the throttled function. + This is useful for rate-limiting API calls, handling scroll/resize events, or any scenario where you want to ensure a maximum execution frequency. @@ -24,13 +28,13 @@ ensure a maximum execution frequency. ```ts const throttler = new AsyncThrottler(async (value: string) => { - await saveToAPI(value); + const result = await saveToAPI(value); + return result; // Return value is preserved }, { wait: 1000 }); // Will only execute once per second no matter how often called -inputElement.addEventListener('input', () => { - throttler.maybeExecute(inputElement.value); -}); +// Returns the API response directly +const result = await throttler.maybeExecute(inputElement.value); ``` ## Type Parameters @@ -45,7 +49,7 @@ inputElement.addEventListener('input', () => { new AsyncThrottler(fn, initialOptions): AsyncThrottler ``` -Defined in: [async-throttler.ts:89](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L89) +Defined in: [async-throttler.ts:93](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L93) #### Parameters @@ -69,7 +73,7 @@ Defined in: [async-throttler.ts:89](https://github.com/TanStack/pacer/blob/main/ cancel(): void ``` -Defined in: [async-throttler.ts:187](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L187) +Defined in: [async-throttler.ts:191](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L191) Cancels any pending execution or aborts any execution in progress @@ -85,7 +89,7 @@ Cancels any pending execution or aborts any execution in progress getErrorCount(): number ``` -Defined in: [async-throttler.ts:237](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L237) +Defined in: [async-throttler.ts:241](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L241) Returns the number of times the function has errored @@ -101,7 +105,7 @@ Returns the number of times the function has errored getIsExecuting(): boolean ``` -Defined in: [async-throttler.ts:251](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L251) +Defined in: [async-throttler.ts:255](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L255) Returns the current executing state @@ -117,7 +121,7 @@ Returns the current executing state getIsPending(): boolean ``` -Defined in: [async-throttler.ts:244](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L244) +Defined in: [async-throttler.ts:248](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L248) Returns the current pending state @@ -133,7 +137,7 @@ Returns the current pending state getLastExecutionTime(): number ``` -Defined in: [async-throttler.ts:202](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L202) +Defined in: [async-throttler.ts:206](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L206) Returns the last execution time @@ -149,7 +153,7 @@ Returns the last execution time getLastResult(): undefined | ReturnType ``` -Defined in: [async-throttler.ts:216](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L216) +Defined in: [async-throttler.ts:220](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L220) Returns the last result of the debounced function @@ -165,7 +169,7 @@ Returns the last result of the debounced function getNextExecutionTime(): number ``` -Defined in: [async-throttler.ts:209](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L209) +Defined in: [async-throttler.ts:213](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L213) Returns the next execution time @@ -181,7 +185,7 @@ Returns the next execution time getOptions(): Required> ``` -Defined in: [async-throttler.ts:115](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L115) +Defined in: [async-throttler.ts:119](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L119) Returns the current options @@ -197,7 +201,7 @@ Returns the current options getSettleCount(): number ``` -Defined in: [async-throttler.ts:230](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L230) +Defined in: [async-throttler.ts:234](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L234) Returns the number of times the function has settled (completed or errored) @@ -213,7 +217,7 @@ Returns the number of times the function has settled (completed or errored) getSuccessCount(): number ``` -Defined in: [async-throttler.ts:223](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L223) +Defined in: [async-throttler.ts:227](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L227) Returns the number of times the function has been executed successfully @@ -229,7 +233,7 @@ Returns the number of times the function has been executed successfully maybeExecute(...args): Promise> ``` -Defined in: [async-throttler.ts:123](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L123) +Defined in: [async-throttler.ts:127](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L127) Attempts to execute the throttled function If a call is already in progress, it may be blocked or queued depending on the `wait` option @@ -252,7 +256,7 @@ If a call is already in progress, it may be blocked or queued depending on the ` setOptions(newOptions): void ``` -Defined in: [async-throttler.ts:103](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L103) +Defined in: [async-throttler.ts:107](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L107) Updates the throttler options Returns the new options state diff --git a/docs/ru/reference/classes/ratelimiter.md b/docs/ru/reference/classes/ratelimiter.md index 4d90d389c..aa78b4888 100644 --- a/docs/ru/reference/classes/ratelimiter.md +++ b/docs/ru/reference/classes/ratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:17:21.104Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:59:36.035Z' id: RateLimiter title: RateLimiter --- @@ -9,7 +9,7 @@ title: RateLimiter # Class: RateLimiter\ -Defined in: [rate-limiter.ts:63](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L63) +Defined in: [rate-limiter.ts:77](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L77) A class that creates a rate-limited function. @@ -17,6 +17,12 @@ Rate limiting is a simple approach that allows a function to execute up to a lim then blocks all subsequent calls until the window passes. This can lead to "bursty" behavior where all executions happen immediately, followed by a complete block. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns, consider using: - Throttling: Ensures consistent spacing between executions (e.g. max once per 200ms) - Debouncing: Waits for a pause in calls before executing (e.g. after 500ms of no calls) @@ -29,7 +35,7 @@ smoothing out frequent events, throttling or debouncing usually provide better u ```ts const rateLimiter = new RateLimiter( (id: string) => api.getData(id), - { limit: 5, window: 1000 } // 5 calls per second + { limit: 5, window: 1000, windowType: 'sliding' } // 5 calls per second with sliding window ); // Will execute immediately until limit reached, then block @@ -48,7 +54,7 @@ rateLimiter.maybeExecute('123'); new RateLimiter(fn, initialOptions): RateLimiter ``` -Defined in: [rate-limiter.ts:69](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L69) +Defined in: [rate-limiter.ts:83](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L83) #### Parameters @@ -72,7 +78,7 @@ Defined in: [rate-limiter.ts:69](https://github.com/TanStack/pacer/blob/main/pac getExecutionCount(): number ``` -Defined in: [rate-limiter.ts:149](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L149) +Defined in: [rate-limiter.ts:175](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L175) Returns the number of times the function has been executed @@ -88,7 +94,7 @@ Returns the number of times the function has been executed getMsUntilNextWindow(): number ``` -Defined in: [rate-limiter.ts:171](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L171) +Defined in: [rate-limiter.ts:197](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L197) Returns the number of milliseconds until the next execution will be possible @@ -104,7 +110,7 @@ Returns the number of milliseconds until the next execution will be possible getOptions(): Required> ``` -Defined in: [rate-limiter.ts:90](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L90) +Defined in: [rate-limiter.ts:104](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L104) Returns the current rate limiter options @@ -120,7 +126,7 @@ Returns the current rate limiter options getRejectionCount(): number ``` -Defined in: [rate-limiter.ts:156](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L156) +Defined in: [rate-limiter.ts:182](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L182) Returns the number of times the function has been rejected @@ -136,7 +142,7 @@ Returns the number of times the function has been rejected getRemainingInWindow(): number ``` -Defined in: [rate-limiter.ts:163](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L163) +Defined in: [rate-limiter.ts:189](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L189) Returns the number of remaining executions allowed in the current window @@ -152,7 +158,7 @@ Returns the number of remaining executions allowed in the current window maybeExecute(...args): boolean ``` -Defined in: [rate-limiter.ts:109](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L109) +Defined in: [rate-limiter.ts:123](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L123) Attempts to execute the rate-limited function if within the configured limits. Will reject execution if the number of calls in the current window exceeds the limit. @@ -187,7 +193,7 @@ rateLimiter.maybeExecute('arg1', 'arg2'); // false reset(): void ``` -Defined in: [rate-limiter.ts:179](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L179) +Defined in: [rate-limiter.ts:208](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L208) Resets the rate limiter state @@ -203,7 +209,7 @@ Resets the rate limiter state setOptions(newOptions): void ``` -Defined in: [rate-limiter.ts:83](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L83) +Defined in: [rate-limiter.ts:97](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L97) Updates the rate limiter options Returns the new options state diff --git a/docs/ru/reference/functions/asyncdebounce.md b/docs/ru/reference/functions/asyncdebounce.md index 1d4ef74f6..6787ddcbd 100644 --- a/docs/ru/reference/functions/asyncdebounce.md +++ b/docs/ru/reference/functions/asyncdebounce.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-04-24T02:14:56.000Z' -translation-updated-at: '2025-05-06T20:43:58.729Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:59:36.031Z' id: asyncDebounce title: asyncDebounce --- @@ -10,21 +10,23 @@ title: asyncDebounce # Function: asyncDebounce() ```ts -function asyncDebounce(fn, initialOptions): (...args) => Promise +function asyncDebounce(fn, initialOptions): (...args) => Promise> ``` -Defined in: [async-debouncer.ts:219](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L219) +Defined in: [async-debouncer.ts:268](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L268) Creates an async debounced function that delays execution until after a specified wait time. The debounced function will only execute once the wait period has elapsed without any new calls. If called again during the wait period, the timer resets and a new wait period begins. +Unlike the non-async Debouncer, this async version supports returning values from the debounced function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the debounced function. + ## Type Parameters • **TFn** *extends* [`AnyAsyncFunction`](../type-aliases/anyasyncfunction.md) -• **TArgs** *extends* `any`[] - ## Parameters ### fn @@ -33,7 +35,7 @@ If called again during the wait period, the timer resets and a new wait period b ### initialOptions -`Omit`\<[`AsyncDebouncerOptions`](../interfaces/asyncdebounceroptions.md)\<`TFn`, `TArgs`\>, `"enabled"`\> +`Omit`\<[`AsyncDebouncerOptions`](../interfaces/asyncdebounceroptions.md)\<`TFn`\>, `"enabled"`\> ## Returns @@ -46,21 +48,21 @@ If a call is already in progress, it will be queued #### args -...`TArgs` +...`Parameters`\<`TFn`\> ### Returns -`Promise`\<`void`\> +`Promise`\<`undefined` \| `ReturnType`\<`TFn`\>\> ## Example ```ts const debounced = asyncDebounce(async (value: string) => { - await saveToAPI(value); + const result = await saveToAPI(value); + return result; // Return value is preserved }, { wait: 1000 }); // Will only execute once, 1 second after the last call -await debounced("first"); // Cancelled -await debounced("second"); // Cancelled -await debounced("third"); // Executes after 1s +// Returns the API response directly +const result = await debounced("third"); ``` diff --git a/docs/ru/reference/functions/asyncratelimit.md b/docs/ru/reference/functions/asyncratelimit.md index c47a0040e..bded3d26b 100644 --- a/docs/ru/reference/functions/asyncratelimit.md +++ b/docs/ru/reference/functions/asyncratelimit.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:17:21.094Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:59:36.027Z' id: asyncRateLimit title: asyncRateLimit --- @@ -13,10 +13,20 @@ title: asyncRateLimit function asyncRateLimit(fn, initialOptions): (...args) => Promise> ``` -Defined in: [async-rate-limiter.ts:262](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L262) +Defined in: [async-rate-limiter.ts:322](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L322) Creates an async rate-limited function that will execute the provided function up to a maximum number of times within a time window. +Unlike the non-async rate limiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + Note that rate limiting is a simpler form of execution control compared to throttling or debouncing: - A rate limiter will allow all executions until the limit is reached, then block all subsequent calls until the window resets - A throttler ensures even spacing between executions, which can be better for consistent performance @@ -72,10 +82,11 @@ await rateLimiter.maybeExecute('arg1', 'arg2'); // Rejected ## Example ```ts -// Rate limit to 5 calls per minute +// Rate limit to 5 calls per minute with a sliding window const rateLimited = asyncRateLimit(makeApiCall, { limit: 5, window: 60000, + windowType: 'sliding', onReject: (rateLimiter) => { console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } @@ -83,7 +94,8 @@ const rateLimited = asyncRateLimit(makeApiCall, { // First 5 calls will execute immediately // Additional calls will be rejected until the minute window resets -await rateLimited(); +// Returns the API response directly +const result = await rateLimited(); // For more even execution, consider using throttle instead: const throttled = throttle(makeApiCall, { wait: 12000 }); // One call every 12 seconds diff --git a/docs/ru/reference/functions/asyncthrottle.md b/docs/ru/reference/functions/asyncthrottle.md index c027d3561..f148e708f 100644 --- a/docs/ru/reference/functions/asyncthrottle.md +++ b/docs/ru/reference/functions/asyncthrottle.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-04-24T02:14:56.000Z' -translation-updated-at: '2025-05-06T20:43:58.720Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:59:36.023Z' id: asyncThrottle title: asyncThrottle --- @@ -10,21 +10,23 @@ title: asyncThrottle # Function: asyncThrottle() ```ts -function asyncThrottle(fn, initialOptions): (...args) => Promise +function asyncThrottle(fn, initialOptions): (...args) => Promise> ``` -Defined in: [async-throttler.ts:223](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L223) +Defined in: [async-throttler.ts:281](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L281) Creates an async throttled function that limits how often the function can execute. The throttled function will execute at most once per wait period, even if called multiple times. If called while executing, it will wait until execution completes before scheduling the next call. +Unlike the non-async Throttler, this async version supports returning values from the throttled function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the throttled function. + ## Type Parameters • **TFn** *extends* [`AnyAsyncFunction`](../type-aliases/anyasyncfunction.md) -• **TArgs** *extends* `any`[] - ## Parameters ### fn @@ -33,7 +35,7 @@ If called while executing, it will wait until execution completes before schedul ### initialOptions -`Omit`\<[`AsyncThrottlerOptions`](../interfaces/asyncthrottleroptions.md)\<`TFn`, `TArgs`\>, `"enabled"`\> +`Omit`\<[`AsyncThrottlerOptions`](../interfaces/asyncthrottleroptions.md)\<`TFn`\>, `"enabled"`\> ## Returns @@ -46,20 +48,21 @@ If a call is already in progress, it may be blocked or queued depending on the ` #### args -...`TArgs` +...`Parameters`\<`TFn`\> ### Returns -`Promise`\<`void`\> +`Promise`\<`undefined` \| `ReturnType`\<`TFn`\>\> ## Example ```ts -const throttled = asyncThrottle(async () => { - await someAsyncOperation(); +const throttled = asyncThrottle(async (value: string) => { + const result = await saveToAPI(value); + return result; // Return value is preserved }, { wait: 1000 }); // This will execute at most once per second -await throttled(); -await throttled(); // Waits 1 second before executing +// Returns the API response directly +const result = await throttled(inputElement.value); ``` diff --git a/docs/ru/reference/functions/ratelimit.md b/docs/ru/reference/functions/ratelimit.md index 38c98e54d..3100737e6 100644 --- a/docs/ru/reference/functions/ratelimit.md +++ b/docs/ru/reference/functions/ratelimit.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:17:21.087Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:59:36.019Z' id: rateLimit title: rateLimit --- @@ -13,7 +13,7 @@ title: rateLimit function rateLimit(fn, initialOptions): (...args) => boolean ``` -Defined in: [rate-limiter.ts:216](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L216) +Defined in: [rate-limiter.ts:252](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L252) Creates a rate-limited function that will execute the provided function up to a maximum number of times within a time window. @@ -22,6 +22,12 @@ Note that rate limiting is a simpler form of execution control compared to throt - A throttler ensures even spacing between executions, which can be better for consistent performance - A debouncer collapses multiple calls into one, which is better for handling bursts of events +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + Consider using throttle() or debounce() if you need more intelligent execution control. Use rate limiting when you specifically need to enforce a hard limit on the number of executions within a time period. @@ -71,10 +77,11 @@ rateLimiter.maybeExecute('arg1', 'arg2'); // false ## Example ```ts -// Rate limit to 5 calls per minute +// Rate limit to 5 calls per minute with a sliding window const rateLimited = rateLimit(makeApiCall, { limit: 5, window: 60000, + windowType: 'sliding', onReject: (rateLimiter) => { console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/ru/reference/interfaces/asyncratelimiteroptions.md b/docs/ru/reference/interfaces/asyncratelimiteroptions.md index a20fce0eb..373abb11a 100644 --- a/docs/ru/reference/interfaces/asyncratelimiteroptions.md +++ b/docs/ru/reference/interfaces/asyncratelimiteroptions.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:17:21.068Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:59:36.015Z' id: AsyncRateLimiterOptions title: AsyncRateLimiterOptions --- @@ -149,3 +149,18 @@ window: number; Defined in: [async-rate-limiter.ts:38](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L38) Time window in milliseconds within which the limit applies + +*** + +### windowType? + +```ts +optional windowType: "fixed" | "sliding"; +``` + +Defined in: [async-rate-limiter.ts:45](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L45) + +Type of window to use for rate limiting +- 'fixed': Uses a fixed window that resets after the window period +- 'sliding': Uses a sliding window that allows executions as old ones expire +Defaults to 'fixed' diff --git a/docs/ru/reference/interfaces/ratelimiteroptions.md b/docs/ru/reference/interfaces/ratelimiteroptions.md index 7cac919d2..5c9a6f269 100644 --- a/docs/ru/reference/interfaces/ratelimiteroptions.md +++ b/docs/ru/reference/interfaces/ratelimiteroptions.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:17:21.041Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:59:36.011Z' id: RateLimiterOptions title: RateLimiterOptions --- @@ -97,3 +97,18 @@ window: number; Defined in: [rate-limiter.ts:27](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L27) Time window in milliseconds within which the limit applies + +*** + +### windowType? + +```ts +optional windowType: "fixed" | "sliding"; +``` + +Defined in: [rate-limiter.ts:34](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L34) + +Type of window to use for rate limiting +- 'fixed': Uses a fixed window that resets after the window period +- 'sliding': Uses a sliding window that allows executions as old ones expire +Defaults to 'fixed' diff --git a/docs/zh-hans/framework/react/reference/functions/useasyncratelimiter.md b/docs/zh-hans/framework/react/reference/functions/useasyncratelimiter.md index 34de2d2fa..fd2c3611c 100644 --- a/docs/zh-hans/framework/react/reference/functions/useasyncratelimiter.md +++ b/docs/zh-hans/framework/react/reference/functions/useasyncratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:02:12.851Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:42:47.818Z' id: useAsyncRateLimiter title: useAsyncRateLimiter --- @@ -13,7 +13,7 @@ title: useAsyncRateLimiter function useAsyncRateLimiter(fn, options): AsyncRateLimiter ``` -Defined in: [react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts:43](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts#L43) +Defined in: [react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts:54](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts#L54) A low-level React hook that creates an `AsyncRateLimiter` instance to limit how many times an async function can execute within a time window. @@ -24,6 +24,16 @@ Rate limiting allows an async function to execute up to a specified limit within then blocks subsequent calls until the window passes. This is useful for respecting API rate limits, managing resource constraints, or controlling bursts of async operations. +Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + ## Type Parameters • **TFn** *extends* `AnyAsyncFunction` @@ -45,21 +55,22 @@ managing resource constraints, or controlling bursts of async operations. ## Example ```tsx -// Basic API call rate limiting +// Basic API call rate limiting with return value const { maybeExecute } = useAsyncRateLimiter( async (id: string) => { const data = await api.fetchData(id); - return data; + return data; // Return value is preserved }, { limit: 5, window: 1000 } // 5 calls per second ); -// With state management +// With state management and return value const [data, setData] = useState(null); const { maybeExecute } = useAsyncRateLimiter( async (query) => { const result = await searchAPI(query); setData(result); + return result; // Return value can be used by the caller }, { limit: 10, diff --git a/docs/zh-hans/framework/react/reference/functions/useratelimitedcallback.md b/docs/zh-hans/framework/react/reference/functions/useratelimitedcallback.md index 03f98546a..5c9f3d07d 100644 --- a/docs/zh-hans/framework/react/reference/functions/useratelimitedcallback.md +++ b/docs/zh-hans/framework/react/reference/functions/useratelimitedcallback.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-04-24T02:14:56.000Z' -translation-updated-at: '2025-05-06T20:25:55.558Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:42:47.814Z' id: useRateLimitedCallback title: useRateLimitedCallback --- @@ -13,7 +13,7 @@ title: useRateLimitedCallback function useRateLimitedCallback(fn, options): (...args) => boolean ``` -Defined in: [rate-limiter/useRateLimitedCallback.ts:52](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedCallback.ts#L52) +Defined in: [react-pacer/src/rate-limiter/useRateLimitedCallback.ts:59](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedCallback.ts#L59) A React hook that creates a rate-limited version of a callback function. This hook is essentially a wrapper around the basic `rateLimiter` function @@ -26,6 +26,12 @@ or debouncing, it does not attempt to space out or intelligently collapse calls. This can lead to bursts of rapid executions followed by periods where all calls are blocked. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns, consider: - useThrottledCallback: When you want consistent spacing between executions (e.g. UI updates) - useDebouncedCallback: When you want to collapse rapid calls into a single execution (e.g. search input) @@ -57,7 +63,7 @@ Consider using the `useRateLimiter` hook instead. ### options -`RateLimiterOptions`\<`TFn`, `TArgs`\> +`RateLimiterOptions`\<`TFn`\> ## Returns @@ -76,7 +82,7 @@ Consider using the `useRateLimiter` hook instead. ## Example ```tsx -// Rate limit API calls to maximum 5 calls per minute +// Rate limit API calls to maximum 5 calls per minute with a sliding window const makeApiCall = useRateLimitedCallback( (data: ApiData) => { return fetch('/api/endpoint', { method: 'POST', body: JSON.stringify(data) }); @@ -84,6 +90,7 @@ const makeApiCall = useRateLimitedCallback( { limit: 5, window: 60000, // 1 minute + windowType: 'sliding', onReject: () => { console.warn('API rate limit reached. Please wait before trying again.'); } diff --git a/docs/zh-hans/framework/react/reference/functions/useratelimitedstate.md b/docs/zh-hans/framework/react/reference/functions/useratelimitedstate.md index a21e68d92..bebad3917 100644 --- a/docs/zh-hans/framework/react/reference/functions/useratelimitedstate.md +++ b/docs/zh-hans/framework/react/reference/functions/useratelimitedstate.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:02:12.814Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:42:47.811Z' id: useRateLimitedState title: useRateLimitedState --- @@ -13,7 +13,7 @@ title: useRateLimitedState function useRateLimitedState(value, options): [TValue, Dispatch>, RateLimiter>>] ``` -Defined in: [react-pacer/src/rate-limiter/useRateLimitedState.ts:59](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedState.ts#L59) +Defined in: [react-pacer/src/rate-limiter/useRateLimitedState.ts:66](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedState.ts#L66) A React hook that creates a rate-limited state value that enforces a hard limit on state updates within a time window. This hook combines React's useState with rate limiting functionality to provide controlled state updates. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - useThrottledState: When you want consistent spacing between updates (e.g. UI changes) - useDebouncedState: When you want to collapse rapid updates into a single update (e.g. search input) @@ -57,16 +63,18 @@ consider using the lower-level useRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update state at most 5 times per minute +// Basic rate limiting - update state at most 5 times per minute with a sliding window const [value, setValue, rateLimiter] = useRateLimitedState(0, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); -// With rejection callback +// With rejection callback and fixed window const [value, setValue] = useRateLimitedState(0, { limit: 3, window: 5000, + windowType: 'fixed', onReject: (rateLimiter) => { alert(`Rate limit reached. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/zh-hans/framework/react/reference/functions/useratelimitedvalue.md b/docs/zh-hans/framework/react/reference/functions/useratelimitedvalue.md index cb2406f28..e976eb929 100644 --- a/docs/zh-hans/framework/react/reference/functions/useratelimitedvalue.md +++ b/docs/zh-hans/framework/react/reference/functions/useratelimitedvalue.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:02:12.808Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:42:47.807Z' id: useRateLimitedValue title: useRateLimitedValue --- @@ -13,7 +13,7 @@ title: useRateLimitedValue function useRateLimitedValue(value, options): [TValue, RateLimiter>>] ``` -Defined in: [react-pacer/src/rate-limiter/useRateLimitedValue.ts:47](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedValue.ts#L47) +Defined in: [react-pacer/src/rate-limiter/useRateLimitedValue.ts:55](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedValue.ts#L55) A high-level React hook that creates a rate-limited version of a value that updates at most a certain number of times within a time window. This hook uses React's useState internally to manage the rate-limited state. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - useThrottledValue: When you want consistent spacing between updates (e.g. UI changes) - useDebouncedValue: When you want to collapse rapid updates into a single update (e.g. search input) @@ -56,16 +62,18 @@ consider using the lower-level useRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update at most 5 times per minute +// Basic rate limiting - update at most 5 times per minute with a sliding window const [rateLimitedValue, rateLimiter] = useRateLimitedValue(rawValue, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); -// With rejection callback +// With rejection callback and fixed window const [rateLimitedValue, rateLimiter] = useRateLimitedValue(rawValue, { limit: 3, window: 5000, + windowType: 'fixed', onReject: (rateLimiter) => { console.log(`Update rejected. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/zh-hans/framework/react/reference/functions/useratelimiter.md b/docs/zh-hans/framework/react/reference/functions/useratelimiter.md index 50ad11b4f..99b4ecd4e 100644 --- a/docs/zh-hans/framework/react/reference/functions/useratelimiter.md +++ b/docs/zh-hans/framework/react/reference/functions/useratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:02:12.804Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:42:47.803Z' id: useRateLimiter title: useRateLimiter --- @@ -13,7 +13,7 @@ title: useRateLimiter function useRateLimiter(fn, options): RateLimiter ``` -Defined in: [react-pacer/src/rate-limiter/useRateLimiter.ts:48](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimiter.ts#L48) +Defined in: [react-pacer/src/rate-limiter/useRateLimiter.ts:55](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimiter.ts#L55) A low-level React hook that creates a `RateLimiter` instance to enforce rate limits on function execution. @@ -24,6 +24,12 @@ Rate limiting is a simple "hard limit" approach that allows executions until a m a time window, then blocks all subsequent calls until the window resets. Unlike throttling or debouncing, it does not attempt to space out or collapse executions intelligently. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns: - Use throttling when you want consistent spacing between executions (e.g. UI updates) - Use debouncing when you want to collapse rapid-fire events (e.g. search input) @@ -57,10 +63,11 @@ The hook returns an object containing: ## Example ```tsx -// Basic rate limiting - max 5 calls per minute +// Basic rate limiting - max 5 calls per minute with a sliding window const { maybeExecute } = useRateLimiter(apiCall, { limit: 5, window: 60000, + windowType: 'sliding', }); // Monitor rate limit status diff --git a/docs/zh-hans/framework/solid/reference/functions/createasyncratelimiter.md b/docs/zh-hans/framework/solid/reference/functions/createasyncratelimiter.md index 5a452a2b7..f16156be2 100644 --- a/docs/zh-hans/framework/solid/reference/functions/createasyncratelimiter.md +++ b/docs/zh-hans/framework/solid/reference/functions/createasyncratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:02:12.776Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:42:47.797Z' id: createAsyncRateLimiter title: createAsyncRateLimiter --- @@ -13,7 +13,7 @@ title: createAsyncRateLimiter function createAsyncRateLimiter(fn, initialOptions): SolidAsyncRateLimiter ``` -Defined in: [async-rate-limiter/createAsyncRateLimiter.ts:62](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L62) +Defined in: [async-rate-limiter/createAsyncRateLimiter.ts:73](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L73) A low-level Solid hook that creates an `AsyncRateLimiter` instance to limit how many times an async function can execute within a time window. @@ -24,6 +24,16 @@ Rate limiting allows an async function to execute up to a specified limit within then blocks subsequent calls until the window passes. This is useful for respecting API rate limits, managing resource constraints, or controlling bursts of async operations. +Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + ## Type Parameters • **TFn** *extends* `AnyAsyncFunction` @@ -45,21 +55,22 @@ managing resource constraints, or controlling bursts of async operations. ## Example ```tsx -// Basic API call rate limiting +// Basic API call rate limiting with return value const { maybeExecute } = createAsyncRateLimiter( async (id: string) => { const data = await api.fetchData(id); - return data; + return data; // Return value is preserved }, { limit: 5, window: 1000 } // 5 calls per second ); -// With state management +// With state management and return value const [data, setData] = createSignal(null); const { maybeExecute } = createAsyncRateLimiter( async (query) => { const result = await searchAPI(query); setData(result); + return result; // Return value can be used by the caller }, { limit: 10, diff --git a/docs/zh-hans/framework/solid/reference/functions/createratelimitedsignal.md b/docs/zh-hans/framework/solid/reference/functions/createratelimitedsignal.md index 5fdd9524b..6d718ea8e 100644 --- a/docs/zh-hans/framework/solid/reference/functions/createratelimitedsignal.md +++ b/docs/zh-hans/framework/solid/reference/functions/createratelimitedsignal.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:02:12.752Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:42:47.794Z' id: createRateLimitedSignal title: createRateLimitedSignal --- @@ -13,7 +13,7 @@ title: createRateLimitedSignal function createRateLimitedSignal(value, initialOptions): [Accessor, Setter, SolidRateLimiter>] ``` -Defined in: [rate-limiter/createRateLimitedSignal.ts:57](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedSignal.ts#L57) +Defined in: [rate-limiter/createRateLimitedSignal.ts:65](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedSignal.ts#L65) A Solid hook that creates a rate-limited state value that enforces a hard limit on state updates within a time window. This hook combines Solid's createSignal with rate limiting functionality to provide controlled state updates. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - createThrottledSignal: When you want consistent spacing between updates (e.g. UI changes) - createDebouncedSignal: When you want to collapse rapid updates into a single update (e.g. search input) @@ -57,16 +63,18 @@ consider using the lower-level createRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update state at most 5 times per minute +// Basic rate limiting - update state at most 5 times per minute with a sliding window const [value, setValue, rateLimiter] = createRateLimitedSignal(0, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); -// With rejection callback +// With rejection callback and fixed window const [value, setValue] = createRateLimitedSignal(0, { limit: 3, window: 5000, + windowType: 'fixed', onReject: (rateLimiter) => { alert(`Rate limit reached. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/zh-hans/framework/solid/reference/functions/createratelimitedvalue.md b/docs/zh-hans/framework/solid/reference/functions/createratelimitedvalue.md index f90888960..3c7a5c888 100644 --- a/docs/zh-hans/framework/solid/reference/functions/createratelimitedvalue.md +++ b/docs/zh-hans/framework/solid/reference/functions/createratelimitedvalue.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:02:12.747Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:42:47.790Z' id: createRateLimitedValue title: createRateLimitedValue --- @@ -13,7 +13,7 @@ title: createRateLimitedValue function createRateLimitedValue(value, initialOptions): [Accessor, SolidRateLimiter>] ``` -Defined in: [rate-limiter/createRateLimitedValue.ts:43](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedValue.ts#L43) +Defined in: [rate-limiter/createRateLimitedValue.ts:50](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedValue.ts#L50) A high-level Solid hook that creates a rate-limited version of a value that updates at most a certain number of times within a time window. This hook uses Solid's createSignal internally to manage the rate-limited state. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - createThrottledValue: When you want consistent spacing between updates (e.g. UI changes) - createDebouncedValue: When you want to collapse rapid updates into a single update (e.g. search input) @@ -56,10 +62,11 @@ consider using the lower-level createRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update at most 5 times per minute +// Basic rate limiting - update at most 5 times per minute with a sliding window const [rateLimitedValue, rateLimiter] = createRateLimitedValue(rawValue, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); // Use the rate-limited value diff --git a/docs/zh-hans/framework/solid/reference/functions/createratelimiter.md b/docs/zh-hans/framework/solid/reference/functions/createratelimiter.md index 1011acd12..4637df14b 100644 --- a/docs/zh-hans/framework/solid/reference/functions/createratelimiter.md +++ b/docs/zh-hans/framework/solid/reference/functions/createratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:02:12.744Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:42:47.786Z' id: createRateLimiter title: createRateLimiter --- @@ -13,7 +13,7 @@ title: createRateLimiter function createRateLimiter(fn, initialOptions): SolidRateLimiter ``` -Defined in: [rate-limiter/createRateLimiter.ts:61](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts#L61) +Defined in: [rate-limiter/createRateLimiter.ts:68](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts#L68) A low-level Solid hook that creates a `RateLimiter` instance to enforce rate limits on function execution. @@ -24,6 +24,12 @@ Rate limiting is a simple "hard limit" approach that allows executions until a m a time window, then blocks all subsequent calls until the window resets. Unlike throttling or debouncing, it does not attempt to space out or collapse executions intelligently. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns: - Use throttling when you want consistent spacing between executions (e.g. UI updates) - Use debouncing when you want to collapse rapid-fire events (e.g. search input) @@ -50,10 +56,11 @@ For smoother execution patterns: ## Example ```tsx -// Basic rate limiting - max 5 calls per minute +// Basic rate limiting - max 5 calls per minute with a sliding window const rateLimiter = createRateLimiter(apiCall, { limit: 5, window: 60000, + windowType: 'sliding' }); // Monitor rate limit status diff --git a/docs/zh-hans/guides/debouncing.md b/docs/zh-hans/guides/debouncing.md index f87186394..96d5169fd 100644 --- a/docs/zh-hans/guides/debouncing.md +++ b/docs/zh-hans/guides/debouncing.md @@ -1,27 +1,27 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:04:08.175Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:44:45.234Z' title: 防抖指南 id: debouncing --- # 防抖 (Debouncing) 指南 -速率限制 (Rate Limiting)、节流 (Throttling) 和防抖 (Debouncing) 是控制函数执行频率的三种不同方法。每种技术以不同的方式阻止执行,使它们成为"有损"的——意味着当函数被请求过于频繁地运行时,某些调用将不会执行。了解何时使用每种方法对于构建高性能和可靠的应用程序至关重要。本指南将介绍 TanStack Pacer 的防抖概念。 +速率限制 (Rate Limiting)、节流 (Throttling) 和防抖 (Debouncing) 是控制函数执行频率的三种不同方法。每种技术以不同方式阻止执行,使它们成为"有损"的——意味着当函数被请求过于频繁地运行时,某些函数调用将不会执行。了解何时使用每种方法对于构建高性能和可靠的应用程序至关重要。本指南将介绍 TanStack Pacer 的防抖概念。 ## 防抖概念 -防抖是一种延迟函数执行的技术,直到指定的不活动周期结束。与速率限制允许在限制范围内突发执行,或节流确保均匀间隔的执行不同,防抖将多个快速函数调用合并为单个执行,该执行仅在调用停止后发生。这使得防抖非常适合处理事件突发,其中您只关心活动稳定后的最终状态。 +防抖是一种延迟函数执行的技术,直到指定的不活动时间段过去。与允许执行达到限制的速率限制 (Rate Limiting) 或确保均匀间隔执行的节流 (Throttling) 不同,防抖将多个快速函数调用合并为单个执行,该执行仅在调用停止后发生。这使得防抖非常适合处理事件突发,其中您只关心活动停止后的最终状态。 ### 防抖可视化 ```text -防抖 (等待: 3 个时间单位) -时间线: [每秒 1 个时间单位] +防抖 (等待: 3 个刻度) +时间线: [每秒 1 个刻度] 调用: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ 执行: ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ⏳ -> ✅ ❌ ⏳ -> ✅ [=================================================================] - ^ 在此处执行,因为 - 3 个时间单位无调用 + ^ 在此处执行 + 无调用 3 个刻度后 [调用突发] [更多调用] [等待] [新突发] 无执行 重置计时器 [延迟执行] [等待] [延迟执行] @@ -29,34 +29,34 @@ id: debouncing ### 何时使用防抖 -当您希望在采取行动之前等待活动"暂停"时,防抖特别有效。这使得它非常适合处理用户输入或其他快速触发的事件,其中您只关心最终状态。 +当您希望在采取行动之前等待活动"暂停"时,防抖特别有效。这使其非常适合处理用户输入或其他快速触发的事件,其中您只关心最终状态。 -常见用例包括: +常见用例包括: - 搜索输入字段,您希望等待用户完成输入 -- 表单验证,不应在每次按键时运行 -- 窗口大小调整计算,计算成本高 +- 不应在每次按键时运行的表单验证 +- 计算成本高昂的窗口大小调整计算 - 编辑内容时自动保存草稿 -- 仅在用户活动稳定后才应进行的 API 调用 +- 仅在用户活动停止后才应发生的 API 调用 - 任何您只关心快速变化后最终值的场景 ### 何时不使用防抖 -在以下情况下,防抖可能不是最佳选择: -- 您需要在特定时间段内保证执行(改用[节流](../guides/throttling)) -- 您不能错过任何执行(改用[队列](../guides/queueing)) +在以下情况下,防抖可能不是最佳选择: +- 您需要在特定时间段内保证执行 (改用 [节流](../guides/throttling)) +- 您不能错过任何执行 (改用 [队列](../guides/queueing)) ## TanStack Pacer 中的防抖 -TanStack Pacer 分别通过 `Debouncer` 和 `AsyncDebouncer` 类(及其对应的 `debounce` 和 `asyncDebounce` 函数)提供同步和异步防抖。 +TanStack Pacer 通过 `Debouncer` 和 `AsyncDebouncer` 类 (及其对应的 `debounce` 和 `asyncDebounce` 函数) 提供同步和异步防抖。 ### 使用 `debounce` 的基本用法 -`debounce` 函数是为任何函数添加防抖的最简单方法: +`debounce` 函数是为任何函数添加防抖的最简单方法: ```ts import { debounce } from '@tanstack/pacer' -// 防抖搜索输入,等待用户停止输入 +// 防抖搜索输入以等待用户停止输入 const debouncedSearch = debounce( (searchTerm: string) => performSearch(searchTerm), { @@ -71,7 +71,7 @@ searchInput.addEventListener('input', (e) => { ### 使用 `Debouncer` 类的高级用法 -为了更精细地控制防抖行为,您可以直接使用 `Debouncer` 类: +为了更精细地控制防抖行为,您可以直接使用 `Debouncer` 类: ```ts import { Debouncer } from '@tanstack/pacer' @@ -94,7 +94,7 @@ searchDebouncer.cancel() ### 前导和尾随执行 -同步防抖器支持前导和尾随边缘执行: +同步防抖器支持前导和尾随边缘执行: ```ts const debouncedFn = debounce(fn, { @@ -109,35 +109,35 @@ const debouncedFn = debounce(fn, { - `trailing: true` (默认) - 函数在等待期后执行 - `trailing: false` - 等待期后不执行 -常见模式: +常见模式: - `{ leading: false, trailing: true }` - 默认,等待后执行 - `{ leading: true, trailing: false }` - 立即执行,忽略后续调用 - `{ leading: true, trailing: true }` - 在第一次调用和等待后都执行 ### 最大等待时间 -TanStack Pacer 防抖器特意不像其他防抖库那样提供 `maxWait` 选项。如果您需要让执行在更分散的时间段内运行,请考虑改用[节流](../guides/throttling)技术。 +TanStack Pacer 防抖器特意不像其他防抖库那样具有 `maxWait` 选项。如果您需要让执行在更分散的时间段内运行,请考虑改用 [节流](../guides/throttling) 技术。 ### 启用/禁用 -`Debouncer` 类通过 `enabled` 选项支持启用/禁用。使用 `setOptions` 方法,您可以随时启用/禁用防抖器: +`Debouncer` 类通过 `enabled` 选项支持启用/禁用。使用 `setOptions` 方法,您可以随时启用/禁用防抖器: ```ts const debouncer = new Debouncer(fn, { wait: 500, enabled: false }) // 默认禁用 debouncer.setOptions({ enabled: true }) // 随时启用 ``` -如果您使用的是支持响应式选项的框架适配器,可以将 `enabled` 选项设置为条件值以动态启用/禁用防抖器: +如果您使用的是防抖器选项具有响应性的框架适配器,您可以将 `enabled` 选项设置为条件值以动态启用/禁用防抖器: ```ts // React 示例 const debouncer = useDebouncer( setSearch, - { wait: 500, enabled: searchInput.value.length > 3 } // 根据输入长度启用/禁用(如果使用支持响应式选项的框架适配器) + { wait: 500, enabled: searchInput.value.length > 3 } // 根据输入长度启用/禁用 (如果使用支持响应式选项的框架适配器) ) ``` -但是,如果您使用的是 `debounce` 函数或直接使用 `Debouncer` 类,则必须使用 `setOptions` 方法来更改 `enabled` 选项,因为传递的选项实际上是传递给 `Debouncer` 类构造函数的。 +但是,如果您使用的是 `debounce` 函数或直接使用 `Debouncer` 类,则必须使用 `setOptions` 方法来更改 `enabled` 选项,因为传递的选项实际上是传递给 `Debouncer` 类的构造函数。 ```ts // Solid 示例 @@ -149,11 +149,11 @@ createEffect(() => { ### 回调选项 -同步和异步防抖器都支持回调选项来处理防抖生命周期的不同方面: +同步和异步防抖器都支持回调选项来处理防抖生命周期的不同方面: #### 同步防抖器回调 -同步 `Debouncer` 支持以下回调: +同步 `Debouncer` 支持以下回调: ```ts const debouncer = new Debouncer(fn, { @@ -165,7 +165,7 @@ const debouncer = new Debouncer(fn, { }) ``` -`onExecute` 回调在防抖函数每次成功执行后调用,对于跟踪执行、更新 UI 状态或执行清理操作非常有用。 +`onExecute` 回调在防抖函数每次成功执行后被调用,使其适用于跟踪执行、更新 UI 状态或执行清理操作。 #### 异步防抖器回调 @@ -191,37 +191,31 @@ const asyncDebouncer = new AsyncDebouncer(async (value) => { }) ``` -`onSuccess` 回调在防抖函数每次成功执行后调用,而 `onError` 回调在异步函数抛出错误时调用。`onSettled` 回调在每次执行尝试后调用,无论成功与否。这些回调对于跟踪执行计数、更新 UI 状态、处理错误、执行清理操作和记录执行指标特别有用。 +`onSuccess` 回调在防抖函数每次成功执行后被调用,而 `onError` 回调在异步函数抛出错误时被调用。`onSettled` 回调在每次执行尝试后被调用,无论成功或失败。这些回调特别适用于跟踪执行计数、更新 UI 状态、处理错误、执行清理操作和记录执行指标。 ### 异步防抖 -异步防抖器提供了一种强大的方式来处理异步操作的防抖,与同步版本相比具有几个关键优势。虽然同步防抖器非常适合 UI 事件和即时反馈,但异步版本专门设计用于处理 API 调用、数据库操作和其他异步任务。 +异步防抖器提供了一种强大的方法来处理异步操作的防抖,与同步版本相比具有几个关键优势。虽然同步防抖器非常适合 UI 事件和即时反馈,但异步版本专门设计用于处理 API 调用、数据库操作和其他异步任务。 #### 与同步防抖的主要区别 1. **返回值处理** -与返回 void 的同步防抖器不同,异步版本允许您捕获和使用防抖函数的返回值。这在您需要处理 API 调用或其他异步操作的结果时特别有用。`maybeExecute` 方法返回一个 Promise,该 Promise 解析为函数的返回值,允许您等待结果并适当处理。 +与返回 void 的同步防抖器不同,异步版本允许您捕获和使用防抖函数的返回值。这在您需要使用 API 调用或其他异步操作的结果时特别有用。`maybeExecute` 方法返回一个 Promise,该 Promise 解析为函数的返回值,允许您等待结果并适当处理它。 -2. **增强的回调系统** -异步防抖器提供了比同步版本的单一 `onExecute` 回调更复杂的回调系统。该系统包括: -- `onSuccess`:当异步函数成功完成时调用,提供结果和防抖器实例 -- `onError`:当异步函数抛出错误时调用,提供错误和防抖器实例 -- `onSettled`:在每次执行尝试后调用,无论成功与否 +2. **不同的回调** +`AsyncDebouncer` 支持以下回调,而不仅仅是同步版本中的 `onExecute`: +- `onSuccess`: 每次成功执行后调用,提供防抖器实例 +- `onSettled`: 每次执行后调用,提供防抖器实例 +- `onError`: 如果异步函数抛出错误则调用,提供错误和防抖器实例 -3. **执行跟踪** -异步防抖器通过几种方法提供全面的执行跟踪: -- `getSuccessCount()`:成功执行次数 -- `getErrorCount()`:失败执行次数 -- `getSettledCount()`:已解决的执行总数(成功 + 失败) +3. **顺序执行** +由于防抖器的 `maybeExecute` 方法返回一个 Promise,您可以选择在开始下一个执行之前等待每个执行。这使您可以控制执行顺序,并确保每个调用处理最新的数据。这在处理依赖于先前调用结果的操作或保持数据一致性至关重要时特别有用。 -4. **顺序执行** -异步防抖器确保后续执行等待前一次调用完成后再开始。这可以防止执行顺序混乱,并保证每次调用处理最新的数据。这在处理依赖于先前调用结果的操作或维护数据一致性至关重要时尤为重要。 - -例如,如果您正在更新用户的个人资料,然后立即获取其更新后的数据,异步防抖器将确保获取操作等待更新完成,防止出现获取陈旧数据的竞态条件。 +例如,如果您正在更新用户的个人资料,然后立即获取他们更新的数据,您可以在开始获取之前等待更新操作: #### 基本用法示例 -以下是一个基本示例,展示如何将异步防抖器用于搜索操作: +这是一个显示如何使用异步防抖器进行搜索操作的基本示例: ```ts const debouncedSearch = asyncDebounce( @@ -244,24 +238,11 @@ const debouncedSearch = asyncDebounce( const results = await debouncedSearch('query') ``` -#### 高级模式 - -异步防抖器可以与各种模式结合以解决复杂问题: - -1. **状态管理集成** -当将异步防抖器与状态管理系统(如 React 的 useState 或 Solid 的 createSignal)一起使用时,您可以创建强大的模式来处理加载状态、错误状态和数据更新。防抖器的回调为基于操作成功或失败更新 UI 状态提供了完美的钩子。 - -2. **竞态条件预防** -单次飞行变异模式自然可以防止许多场景中的竞态条件。当应用程序的多个部分尝试同时更新同一资源时,防抖器确保只有最近的更新实际发生,同时仍为所有调用者提供结果。 - -3. **错误恢复** -异步防抖器的错误处理能力使其非常适合实现重试逻辑和错误恢复模式。您可以使用 `onError` 回调实现自定义错误处理策略,例如指数退避或回退机制。 - ### 框架适配器 每个框架适配器都提供构建在核心防抖功能之上的钩子,以与框架的状态管理系统集成。每个框架都有可用的钩子,如 `createDebouncer`、`useDebouncedCallback`、`useDebouncedState` 或 `useDebouncedValue`。 -以下是一些示例: +以下是一些示例: #### React diff --git a/docs/zh-hans/guides/rate-limiting.md b/docs/zh-hans/guides/rate-limiting.md index 909a632d7..5d54b94cd 100644 --- a/docs/zh-hans/guides/rate-limiting.md +++ b/docs/zh-hans/guides/rate-limiting.md @@ -1,19 +1,19 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:04:08.933Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:45:08.193Z' title: 限流指南 id: rate-limiting --- # 速率限制 (Rate Limiting) 指南 -速率限制 (Rate Limiting)、节流 (Throttling) 和防抖 (Debouncing) 是控制函数执行频率的三种不同方法。每种技术以不同的方式阻止执行,使它们成为"有损"的 - 意味着当函数被请求过于频繁时,某些调用将不会执行。了解何时使用每种方法对于构建高性能和可靠的应用程序至关重要。本指南将介绍 TanStack Pacer 的速率限制概念。 +速率限制 (Rate Limiting)、节流 (Throttling) 和防抖 (Debouncing) 是控制函数执行频率的三种不同方法。每种技术以不同方式阻止执行,使它们具有"有损性" (lossy) - 意味着当函数被请求过于频繁时,某些调用将不会执行。了解何时使用每种方法对于构建高性能和可靠的应用程序至关重要。本指南将介绍 TanStack Pacer 的速率限制概念。 -> [!注意] -> TanStack Pacer 目前仅是一个前端库。这些是用于客户端速率限制的实用工具。 +> [!NOTE] +> TanStack Pacer 目前仅是一个前端库。这些是用于客户端速率限制 (client-side rate-limiting) 的工具。 ## 速率限制概念 -速率限制是一种限制函数在特定时间窗口内执行速率的技术。它特别适用于需要防止函数被过于频繁调用的场景,例如处理 API 请求或其他外部服务调用时。这是最*简单*的方法,因为它允许执行突发调用,直到达到配额限制。 +速率限制 (Rate Limiting) 是一种限制函数在特定时间窗口内执行速率的技术。它特别适用于需要防止函数被过于频繁调用的场景,例如处理 API 请求或其他外部服务调用。这是最*基础*的方法,因为它允许执行突发调用,直到达到配额限制。 ### 速率限制可视化 @@ -26,9 +26,38 @@ Executed: ✅ ✅ ✅ ❌ ❌ [=== 3 allowed ===][=== blocked until window ends ===][=== new window =======] ``` +### 窗口类型 + +TanStack Pacer 支持两种速率限制窗口类型: + +1. **固定窗口 (Fixed Window)** (默认) + - 严格的窗口,在窗口周期后重置 + - 窗口内的所有执行都计入限制 + - 窗口在周期后完全重置 + - 可能导致窗口边界处的突发行为 + +2. **滑动窗口 (Sliding Window)** + - 滚动窗口,当旧执行过期时允许新执行 + - 随时间提供更一致的执行速率 + - 更适合维持稳定的执行流 + - 防止窗口边界处的突发行为 + +以下是滑动窗口速率限制的可视化: + +```text +Sliding Window Rate Limiting (limit: 3 calls per window) +Timeline: [1 second per tick] + Window 1 | Window 2 +Calls: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ +Executed: ✅ ✅ ✅ ❌ ✅ ✅ ✅ + [=== 3 allowed ===][=== oldest expires, new allowed ===][=== continues sliding =======] +``` + +关键区别在于,使用滑动窗口时,一旦最旧的执行过期,就允许新的执行。与固定窗口方法相比,这创造了更一致的执行流。 + ### 何时使用速率限制 -速率限制在处理可能意外压垮后端服务或导致浏览器性能问题的前端操作时尤为重要。 +速率限制在处理可能意外压倒后端服务或导致浏览器性能问题的前端操作时特别重要。 常见用例包括: - 防止快速用户交互(如按钮点击或表单提交)导致的意外 API 滥用 @@ -37,16 +66,16 @@ Executed: ✅ ✅ ✅ ❌ ❌ ### 何时不使用速率限制 -速率限制是控制函数执行频率最简单的方法。它是这三种技术中最不灵活且限制性最强的。考虑使用[节流](../guides/throttling)或[防抖](../guides/debouncing)来获得更均匀的执行间隔。 +速率限制是控制函数执行频率的最基础方法。它是这三种技术中最不灵活和限制最多的。考虑使用[节流 (throttling)](../guides/throttling) 或[防抖 (debouncing)](../guides/debouncing) 来获得更分散的执行。 -> [!提示] -> 大多数情况下您可能不需要使用"速率限制"。考虑使用[节流](../guides/throttling)或[防抖](../guides/debouncing)替代。 +> [!TIP] +> 对于大多数用例,您可能不希望使用"速率限制"。考虑使用[节流 (throttling)](../guides/throttling) 或[防抖 (debouncing)](../guides/debouncing) 代替。 -速率限制的"有损"特性也意味着某些执行将被拒绝并丢失。如果您需要确保所有执行始终成功,这可能是个问题。如果需要确保所有执行都被排队等待执行,但通过节流延迟来减慢执行速率,请考虑使用[队列](../guides/queueing)。 +速率限制的"有损性" (lossy) 也意味着某些执行将被拒绝和丢失。如果您需要确保所有执行始终成功,这可能是个问题。如果需要确保所有执行都被排队等待执行,但通过节流延迟来减慢执行速率,请考虑使用[队列 (queueing)](../guides/queueing)。 ## TanStack Pacer 中的速率限制 -TanStack Pacer 通过 `RateLimiter` 和 `AsyncRateLimiter` 类(及其对应的 `rateLimit` 和 `asyncRateLimit` 函数)提供同步和异步速率限制功能。 +TanStack Pacer 通过 `RateLimiter` 和 `AsyncRateLimiter` 类(及其对应的 `rateLimit` 和 `asyncRateLimit` 函数)提供同步和异步速率限制。 ### 使用 `rateLimit` 的基本用法 @@ -60,9 +89,10 @@ const rateLimitedApi = rateLimit( (id: string) => fetchUserData(id), { limit: 5, - window: 60 * 1000, // 1 分钟(毫秒) + window: 60 * 1000, // 1 分钟,以毫秒为单位 + windowType: 'fixed', // 默认 onReject: (rateLimiter) => { - console.log(`超过速率限制。请在 ${rateLimiter.getMsUntilNextWindow()} 毫秒后重试`) + console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`) } } ) @@ -73,7 +103,7 @@ rateLimitedApi('user-2') // ✅ 执行 rateLimitedApi('user-3') // ✅ 执行 rateLimitedApi('user-4') // ✅ 执行 rateLimitedApi('user-5') // ✅ 执行 -rateLimitedApi('user-6') // ❌ 拒绝直到窗口重置 +rateLimitedApi('user-6') // ❌ 拒绝,直到窗口重置 ``` ### 使用 `RateLimiter` 类的高级用法 @@ -90,10 +120,10 @@ const limiter = new RateLimiter( limit: 5, window: 60 * 1000, onExecute: (rateLimiter) => { - console.log('函数已执行', rateLimiter.getExecutionCount()) + console.log('Function executed', rateLimiter.getExecutionCount()) }, onReject: (rateLimiter) => { - console.log(`超过速率限制。请在 ${rateLimiter.getMsUntilNextWindow()} 毫秒后重试`) + console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`) } } ) @@ -103,7 +133,7 @@ console.log(limiter.getRemainingInWindow()) // 当前窗口中剩余的调用次 console.log(limiter.getExecutionCount()) // 成功执行的总次数 console.log(limiter.getRejectionCount()) // 被拒绝执行的总次数 -// 尝试执行(返回布尔值表示是否成功) +// 尝试执行(返回表示成功的布尔值) limiter.maybeExecute('user-1') // 动态更新选项 @@ -115,7 +145,10 @@ limiter.reset() ### 启用/禁用 -`RateLimiter` 类支持通过 `enabled` 选项启用/禁用。使用 `setOptions` 方法,您可以随时启用/禁用速率限制器: +`RateLimiter` 类通过 `enabled` 选项支持启用/禁用。使用 `setOptions` 方法,您可以随时启用/禁用速率限制器: + +> [!NOTE] +> `enabled` 选项启用/禁用实际函数执行。禁用速率限制器并不会关闭速率限制,它只是完全阻止函数的执行。 ```ts const limiter = new RateLimiter(fn, { @@ -126,7 +159,7 @@ const limiter = new RateLimiter(fn, { limiter.setOptions({ enabled: true }) // 随时启用 ``` -如果您使用的是框架适配器,其中速率限制器选项是响应式的,您可以将 `enabled` 选项设置为条件值以动态启用/禁用速率限制器。但是,如果您直接使用 `rateLimit` 函数或 `RateLimiter` 类,则必须使用 `setOptions` 方法来更改 `enabled` 选项,因为传递的选项实际上是传递给 `RateLimiter` 类构造函数的。 +如果您使用的是框架适配器,其中速率限制器选项是响应式的,您可以将 `enabled` 选项设置为条件值以动态启用/禁用速率限制器。但是,如果您直接使用 `rateLimit` 函数或 `RateLimiter` 类,则必须使用 `setOptions` 方法来更改 `enabled` 选项,因为传递的选项实际上是传递给 `RateLimiter` 类的构造函数。 ### 回调选项 @@ -142,16 +175,16 @@ const limiter = new RateLimiter(fn, { window: 1000, onExecute: (rateLimiter) => { // 每次成功执行后调用 - console.log('函数已执行', rateLimiter.getExecutionCount()) + console.log('Function executed', rateLimiter.getExecutionCount()) }, onReject: (rateLimiter) => { // 当执行被拒绝时调用 - console.log(`超过速率限制。请在 ${rateLimiter.getMsUntilNextWindow()} 毫秒后重试`) + console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`) } }) ``` -`onExecute` 回调在每次成功执行速率限制函数后调用,而 `onReject` 回调在因速率限制而拒绝执行时调用。这些回调对于跟踪执行、更新 UI 状态或向用户提供反馈非常有用。 +`onExecute` 回调在速率限制函数每次成功执行后调用,而 `onReject` 回调在因速率限制而拒绝执行时调用。这些回调对于跟踪执行、更新 UI 状态或向用户提供反馈非常有用。 #### 异步速率限制器回调 @@ -165,51 +198,46 @@ const asyncLimiter = new AsyncRateLimiter(async (id) => { window: 1000, onExecute: (rateLimiter) => { // 每次成功执行后调用 - console.log('异步函数已执行', rateLimiter.getExecutionCount()) + console.log('Async function executed', rateLimiter.getExecutionCount()) }, onReject: (rateLimiter) => { // 当执行被拒绝时调用 - console.log(`超过速率限制。请在 ${rateLimiter.getMsUntilNextWindow()} 毫秒后重试`) + console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`) }, onError: (error) => { // 如果异步函数抛出错误则调用 - console.error('异步函数失败:', error) + console.error('Async function failed:', error) } }) ``` -`onExecute` 和 `onReject` 回调的工作方式与同步速率限制器相同,而 `onError` 回调允许您优雅地处理错误而不中断速率限制链。这些回调对于跟踪执行计数、更新 UI 状态、处理错误和向用户提供反馈特别有用。 +`onExecute` 和 `onReject` 回调的工作方式与同步速率限制器中的相同,而 `onError` 回调允许您优雅地处理错误而不中断速率限制链。这些回调对于跟踪执行计数、更新 UI 状态、处理错误和向用户提供反馈特别有用。 ### 异步速率限制 -异步速率限制器提供了一种强大的方法来处理带有限速的异步操作,与同步版本相比具有几个关键优势。虽然同步速率限制器适用于 UI 事件和即时反馈,但异步版本专门设计用于处理 API 调用、数据库操作和其他异步任务。 +异步速率限制器提供了一种强大的方法来处理带有限速的异步操作,与同步版本相比具有几个关键优势。虽然同步速率限制器非常适合 UI 事件和即时反馈,但异步版本专门设计用于处理 API 调用、数据库操作和其他异步任务。 #### 与同步速率限制的主要区别 1. **返回值处理** -与返回布尔值表示成功的同步速率限制器不同,异步版本允许您捕获和使用来自速率限制函数的返回值。这在需要使用 API 调用或其他异步操作的结果时特别有用。`maybeExecute` 方法返回一个 Promise,该 Promise 解析为函数的返回值,允许您等待结果并适当处理。 +与返回表示成功的布尔值的同步速率限制器不同,异步版本允许您捕获和使用来自速率限制函数的返回值。这在您需要使用 API 调用或其他异步操作的结果时特别有用。`maybeExecute` 方法返回一个 Promise,该 Promise 解析为函数的返回值,允许您等待结果并适当处理它。 -2. **增强的回调系统** -异步速率限制器提供了比同步版本更复杂的回调系统。该系统包括: -- `onExecute`:每次成功执行后调用,提供速率限制器实例 -- `onReject`:当执行因速率限制被拒绝时调用,提供速率限制器实例 +2. **不同的回调** +`AsyncRateLimiter` 支持以下回调,而不仅仅是同步版本中的 `onExecute`: +- `onSuccess`:每次成功执行后调用,提供速率限制器实例 +- `onSettled`:每次执行后调用,提供速率限制器实例 - `onError`:如果异步函数抛出错误则调用,提供错误和速率限制器实例 -3. **执行跟踪** -异步速率限制器通过几种方法提供全面的执行跟踪: -- `getExecutionCount()`:成功执行的次数 -- `getRejectionCount()`:被拒绝执行的次数 -- `getRemainingInWindow()`:当前窗口中剩余的可用执行次数 -- `getMsUntilNextWindow()`:距离下一个窗口开始的毫秒数 +异步和同步速率限制器都支持 `onReject` 回调来处理被阻止的执行。 -4. **顺序执行** -异步速率限制器确保后续执行等待前一次调用完成后再开始。这防止了执行顺序混乱,并保证每次调用处理最新的数据。这在处理依赖于先前调用结果的操作或维护数据一致性至关重要时尤为重要。 +3. **顺序执行** +由于速率限制器的 `maybeExecute` 方法返回一个 Promise,您可以选择在开始下一个执行之前等待每个执行。这使您可以控制执行顺序,并确保每次调用处理最新的数据。这在处理依赖于先前调用结果的操作或维护数据一致性至关重要时特别有用。 -例如,如果您正在更新用户配置文件然后立即获取其更新后的数据,异步速率限制器将确保获取操作等待更新完成,防止可能出现陈旧数据的竞态条件。 +例如,如果您正在更新用户配置文件然后立即获取其更新后的数据,您可以在开始获取之前等待更新操作: #### 基本用法示例 -以下是一个基本示例,展示如何将异步速率限制器用于 API 操作: +以下是显示如何将异步速率限制器用于 API 操作的基本示例: ```ts const rateLimitedApi = asyncRateLimit( @@ -221,37 +249,24 @@ const rateLimitedApi = asyncRateLimit( limit: 5, window: 1000, onExecute: (limiter) => { - console.log('API 调用成功:', limiter.getExecutionCount()) + console.log('API call succeeded:', limiter.getExecutionCount()) }, onReject: (limiter) => { - console.log(`超过速率限制。请在 ${limiter.getMsUntilNextWindow()} 毫秒后重试`) + console.log(`Rate limit exceeded. Try again in ${limiter.getMsUntilNextWindow()}ms`) }, onError: (error, limiter) => { - console.error('API 调用失败:', error) + console.error('API call failed:', error) } } ) -// 使用 +// 用法 const result = await rateLimitedApi('123') ``` -#### 高级模式 - -异步速率限制器可以与各种模式结合以解决复杂问题: - -1. **状态管理集成** -当将异步速率限制器与状态管理系统(如 React 的 useState 或 Solid 的 createSignal)一起使用时,您可以创建强大的模式来处理加载状态、错误状态和数据更新。速率限制器的回调为基于操作成功或失败更新 UI 状态提供了完美的钩子。 - -2. **竞态条件预防** -速率限制模式自然防止了许多场景中的竞态条件。当应用程序的多个部分尝试同时更新同一资源时,速率限制器确保更新在配置的限制内发生,同时仍向所有调用者提供结果。 - -3. **错误恢复** -异步速率限制器的错误处理能力使其成为实现重试逻辑和错误恢复模式的理想选择。您可以使用 `onError` 回调实现自定义错误处理策略,如指数退避或回退机制。 - ### 框架适配器 -每个框架适配器都提供构建在核心速率限制功能之上的钩子,以与框架的状态管理系统集成。每个框架都提供如 `createRateLimiter`、`useRateLimitedCallback`、`useRateLimitedState` 或 `useRateLimitedValue` 等钩子。 +每个框架适配器都提供构建在核心速率限制功能之上的钩子,以与框架的状态管理系统集成。每个框架都有可用的钩子,如 `createRateLimiter`、`useRateLimitedCallback`、`useRateLimitedState` 或 `useRateLimitedValue`。 以下是一些示例: @@ -275,7 +290,7 @@ const handleFetch = useRateLimitedCallback( // 用于响应式状态管理的基于状态的钩子 const [instantState, setInstantState] = useState('') const [rateLimitedValue] = useRateLimitedValue( - instantState, // 要限制速率的数值 + instantState, // 要限制速率的值 { limit: 5, window: 1000 } ) ``` @@ -296,7 +311,7 @@ const [value, setValue, limiter] = createRateLimitedSignal('', { limit: 5, window: 1000, onExecute: (limiter) => { - console.log('总执行次数:', limiter.getExecutionCount()) + console.log('Total executions:', limiter.getExecutionCount()) } }) ``` diff --git a/docs/zh-hans/guides/throttling.md b/docs/zh-hans/guides/throttling.md index 91062b16d..430c39955 100644 --- a/docs/zh-hans/guides/throttling.md +++ b/docs/zh-hans/guides/throttling.md @@ -1,63 +1,59 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:04:06.670Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:44:37.020Z' title: 节流指南 id: throttling --- -# 节流 (Throttling) 指南 - -TanStack Pacer 是一个专注于为应用程序提供高质量函数执行时序控制工具的库。虽然类似的工具在其他地方也存在,但我们的目标是正确处理所有重要细节 —— 包括 ***类型安全 (type-safety)***、***摇树优化 (tree-shaking)*** 以及一致且 ***直观的 API (intuitive API)***。通过专注于这些基础功能并以 ***框架无关 (framework agnostic)*** 的方式提供它们,我们希望这些工具和模式能在您的应用程序中更加普及。适当的执行控制在应用程序开发中常常被忽视,从而导致性能问题、竞态条件和糟糕的用户体验,而这些本可以通过正确的执行控制来预防。TanStack Pacer 帮助您从一开始就正确实现这些关键模式! - -速率限制 (Rate Limiting)、节流 (Throttling) 和防抖 (Debouncing) 是控制函数执行频率的三种不同方法。每种技术以不同的方式阻止执行,使它们具有"有损 (lossy)"特性 —— 意味着当函数被请求过于频繁时,某些调用将不会执行。了解何时使用每种方法对于构建高性能和可靠的应用程序至关重要。本指南将介绍 TanStack Pacer 的节流概念。 +限流 (Rate Limiting)、节流 (Throttling) 和防抖 (Debouncing) 是控制函数执行频率的三种不同方法。每种技术以不同方式阻止执行,使其具有"有损"特性 —— 意味着当函数被请求过于频繁时,部分调用将不会执行。理解何时使用每种方法对于构建高性能和可靠的应用程序至关重要。本指南将重点介绍 TanStack Pacer 的节流概念。 ## 节流概念 -节流确保函数执行在时间上均匀分布。与允许突发执行直到达到限制的速率限制 (rate limiting) 不同,也与等待活动停止的防抖 (debouncing) 不同,节流通过在调用之间强制执行一致的延迟来创建更平滑的执行模式。如果您设置每秒执行一次的节流,无论请求多么频繁,调用都将均匀间隔。 +节流确保函数执行在时间上均匀分布。与允许突发执行直到达到限制的限流不同,也与等待活动停止的防抖不同,节流通过在调用之间强制执行一致的延迟来创建更平滑的执行模式。如果设置每秒执行一次的节流,无论请求多么频繁,调用都将均匀间隔。 ### 节流可视化 ```text -节流 (每 3 个 tick 执行一次) -时间线: [每秒一个 tick] -调用: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ -执行: ✅ ❌ ⏳ -> ✅ ❌ ❌ ❌ ✅ ✅ +节流(每 3 个时间单位执行一次) +时间轴:[每秒一个刻度] +调用: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ +执行: ✅ ❌ ⏳ -> ✅ ❌ ❌ ❌ ✅ ✅ [=================================================================] - ^ 每 3 个 tick 只允许一次执行, - 无论进行了多少次调用 + ^ 每 3 个刻度仅允许一次执行, + 无论进行多少次调用 - [第一次突发] [更多调用] [间隔调用] - 首次执行后 等待周期后执行 每次等待周期 - 开始节流 结束后执行 + [首次突发] [更多调用] [间隔调用] + 首次执行后 等待周期结束后 每次等待周期 + 开始节流 执行 结束后执行 ``` -### 何时使用节流 +### 适用场景 -节流在您需要一致、可预测的执行时序时特别有效。这使得它非常适合处理频繁事件或更新,在这些情况下您希望获得平滑、受控的行为。 +节流在需要一致、可预测的执行时机时特别有效。这使其成为处理频繁事件或更新的理想选择,在这些场景中您希望获得平滑、受控的行为。 常见用例包括: -- 需要一致时序的 UI 更新(例如进度指示器) -- 不应使浏览器不堪重负的滚动或调整大小事件处理程序 -- 需要一致间隔的实时数据轮询 +- 需要定时一致的 UI 更新(例如进度指示器) +- 不应使浏览器过载的滚动或调整大小事件处理程序 +- 需要固定间隔的实时数据轮询 - 需要稳定节奏的资源密集型操作 - 游戏循环更新或动画帧处理 - 用户输入时的实时搜索建议 -### 何时不使用节流 +### 不适用场景 -在以下情况下,节流可能不是最佳选择: -- 您想等待活动停止(改用[防抖](../guides/debouncing)) -- 您不能错过任何执行(改用[队列](../guides/queueing)) +以下情况可能不适合使用节流: +- 您希望等待活动停止(改用[防抖](../guides/debouncing)) +- 不能错过任何执行(改用[队列](../guides/queueing)) > [!TIP] -> 当您需要平滑、一致的执行时序时,节流通常是最佳选择。它提供了比速率限制更可预测的执行模式,比防抖更即时的反馈。 +> 当需要平滑、一致的执行时机时,节流通常是最佳选择。它比限流提供更可预测的执行模式,比防抖提供更即时的反馈。 ## TanStack Pacer 中的节流 -TanStack Pacer 分别通过 `Throttler` 和 `AsyncThrottler` 类(以及它们对应的 `throttle` 和 `asyncThrottle` 函数)提供同步和异步节流。 +TanStack Pacer 通过 `Throttler` 和 `AsyncThrottler` 类(及其对应的 `throttle` 和 `asyncThrottle` 函数)分别提供同步和异步节流功能。 ### 使用 `throttle` 的基本用法 -`throttle` 函数是为任何函数添加节流的最简单方法: +`throttle` 函数是为任何函数添加节流的最简单方式: ```ts import { throttle } from '@tanstack/pacer' @@ -70,15 +66,15 @@ const throttledUpdate = throttle( } ) -// 在快速循环中,每 200ms 只执行一次 +// 在快速循环中,每 200ms 仅执行一次 for (let i = 0; i < 100; i++) { - throttledUpdate(i) // 许多调用被节流 + throttledUpdate(i) // 许多调用会被节流 } ``` ### 使用 `Throttler` 类的高级用法 -为了更精细地控制节流行为,您可以直接使用 `Throttler` 类: +为了更精细地控制节流行为,可以直接使用 `Throttler` 类: ```ts import { Throttler } from '@tanstack/pacer' @@ -89,34 +85,34 @@ const updateThrottler = new Throttler( ) // 获取执行状态信息 -console.log(updateThrottler.getExecutionCount()) // 成功执行的次数 -console.log(updateThrottler.getLastExecutionTime()) // 最后一次执行的时间戳 +console.log(updateThrottler.getExecutionCount()) // 成功执行次数 +console.log(updateThrottler.getLastExecutionTime()) // 上次执行时间戳 -// 取消任何待执行的调用 +// 取消任何待执行操作 updateThrottler.cancel() ``` -### 前缘和后缘执行 +### 前缘与后缘执行 同步节流器支持前缘和后缘执行: ```ts const throttledFn = throttle(fn, { wait: 200, - leading: true, // 在第一次调用时立即执行(默认) - trailing: true, // 在等待周期后执行(默认) + leading: true, // 首次调用立即执行(默认) + trailing: true, // 等待周期后执行(默认) }) ``` -- `leading: true`(默认)- 在第一次调用时立即执行 -- `leading: false` - 跳过第一次调用,等待后缘执行 -- `trailing: true`(默认)- 在等待周期后执行最后一次调用 +- `leading: true`(默认)- 首次调用立即执行 +- `leading: false` - 跳过首次调用,等待后缘执行 +- `trailing: true`(默认)- 等待周期后执行最后一次调用 - `trailing: false` - 如果在等待周期内则跳过最后一次调用 常见模式: -- `{ leading: true, trailing: true }` - 默认,响应最快 +- `{ leading: true, trailing: true }` - 默认模式,响应最快 - `{ leading: false, trailing: true }` - 延迟所有执行 -- `{ leading: true, trailing: false }` - 跳过排队的执行 +- `{ leading: true, trailing: false }` - 跳过排队执行 ### 启用/禁用 @@ -127,7 +123,7 @@ const throttler = new Throttler(fn, { wait: 200, enabled: false }) // 默认禁 throttler.setOptions({ enabled: true }) // 随时启用 ``` -如果您使用的是节流器选项具有响应性的框架适配器,您可以将 `enabled` 选项设置为条件值以动态启用/禁用节流器。但是,如果您直接使用 `throttle` 函数或 `Throttler` 类,则必须使用 `setOptions` 方法来更改 `enabled` 选项,因为传递的选项实际上是传递给 `Throttler` 类的构造函数。 +如果您使用的是节流器选项具有响应性的框架适配器,可以将 `enabled` 选项设置为条件值以动态启用/禁用节流器。但是,如果直接使用 `throttle` 函数或 `Throttler` 类,则必须使用 `setOptions` 方法来更改 `enabled` 选项,因为传递的选项实际上是传递给 `Throttler` 类的构造函数。 ### 回调选项 @@ -163,43 +159,39 @@ const asyncThrottler = new AsyncThrottler(async (value) => { console.log('异步函数已执行', throttler.getExecutionCount()) }, onError: (error) => { - // 如果异步函数抛出错误则调用 + // 异步函数抛出错误时调用 console.error('异步函数失败:', error) } }) ``` -`onExecute` 回调的工作方式与同步节流器相同,而 `onError` 回调允许您优雅地处理错误而不中断节流链。这些回调对于跟踪执行计数、更新 UI 状态、处理错误、执行清理操作和记录执行指标特别有用。 +`onExecute` 回调的工作方式与同步节流器相同,而 `onError` 回调允许您优雅地处理错误而不中断节流链。这些回调特别适用于跟踪执行次数、更新 UI 状态、处理错误、执行清理操作和记录执行指标。 ### 异步节流 -异步节流器提供了一种强大的方式来处理带节流的异步操作,与同步版本相比具有几个关键优势。虽然同步节流器非常适合 UI 事件和即时反馈,但异步版本专门设计用于处理 API 调用、数据库操作和其他异步任务。 +异步节流器提供了一种强大的方式来处理带节流的异步操作,相比同步版本具有几个关键优势。虽然同步节流器适用于 UI 事件和即时反馈,但异步版本专为处理 API 调用、数据库操作和其他异步任务而设计。 #### 与同步节流的主要区别 1. **返回值处理** -与返回 void 的同步节流器不同,异步版本允许您捕获和使用节流函数的返回值。这在您需要使用 API 调用或其他异步操作的结果时特别有用。`maybeExecute` 方法返回一个 Promise,该 Promise 解析为函数的返回值,允许您等待结果并适当地处理它。 +与返回 void 的同步节流器不同,异步版本允许您捕获和使用节流函数的返回值。这在需要处理 API 调用或其他异步操作的结果时特别有用。`maybeExecute` 方法返回一个 Promise,该 Promise 解析为函数的返回值,允许您等待结果并适当处理。 -2. **增强的回调系统** -异步节流器提供了比同步版本的单一 `onExecute` 回调更复杂的回调系统。该系统包括: -- `onSuccess`:当异步函数成功完成时调用,提供结果和节流器实例 -- `onError`:当异步函数抛出错误时调用,提供错误和节流器实例 -- `onSettled`:在每次执行尝试后调用,无论成功或失败 +2. **不同的回调** +`AsyncThrottler` 支持以下回调,而不仅仅是同步版本中的 `onExecute`: +- `onSuccess`:每次成功执行后调用,提供节流器实例 +- `onSettled`:每次执行后调用,提供节流器实例 +- `onError`:如果异步函数抛出错误则调用,提供错误和节流器实例 -3. **执行跟踪** -异步节流器通过几种方法提供全面的执行跟踪: -- `getSuccessCount()`:成功执行的次数 -- `getErrorCount()`:失败的执行次数 -- `getSettledCount()`:已完成的执行总数(成功 + 失败) +异步和同步节流器都支持 `onExecute` 回调来处理成功执行。 -4. **顺序执行** -异步节流器确保后续执行等待前一个调用完成后再开始。这可以防止执行顺序混乱,并保证每个调用处理最新的数据。这在处理依赖于先前调用结果的操作或维护数据一致性至关重要时尤为重要。 +3. **顺序执行** +由于节流器的 `maybeExecute` 方法返回一个 Promise,您可以选择在开始下一个执行之前等待每个执行完成。这使您可以控制执行顺序,并确保每次调用处理最新的数据。这在处理依赖于先前调用结果的操作或维护数据一致性至关重要时特别有用。 -例如,如果您正在更新用户的个人资料并立即获取其更新后的数据,异步节流器将确保获取操作等待更新完成,防止您可能获取到过时数据的竞态条件。 +例如,如果您正在更新用户的个人资料然后立即获取其更新后的数据,可以在开始获取之前等待更新操作完成: #### 基本用法示例 -以下是一个显示如何使用异步节流器进行搜索操作的基本示例: +以下是展示如何使用异步节流器进行搜索操作的基本示例: ```ts const throttledSearch = asyncThrottle( @@ -222,22 +214,9 @@ const throttledSearch = asyncThrottle( const results = await throttledSearch('query') ``` -#### 高级模式 - -异步节流器可以与各种模式结合以解决复杂问题: - -1. **状态管理集成** -当将异步节流器与状态管理系统(如 React 的 useState 或 Solid 的 createSignal)一起使用时,您可以创建强大的模式来处理加载状态、错误状态和数据更新。节流器的回调为基于操作的成功或失败更新 UI 状态提供了完美的钩子。 - -2. **竞态条件预防** -节流模式自然可以防止许多场景中的竞态条件。当应用程序的多个部分尝试同时更新同一资源时,节流器确保更新以受控速率进行,同时仍向所有调用者提供结果。 - -3. **错误恢复** -异步节流器的错误处理能力使其成为实现重试逻辑和错误恢复模式的理想选择。您可以使用 `onError` 回调实现自定义错误处理策略,例如指数退避或回退机制。 - ### 框架适配器 -每个框架适配器都提供构建在核心节流功能之上的钩子,以与框架的状态管理系统集成。每个框架都有可用的钩子,如 `createThrottler`、`useThrottledCallback`、`useThrottledState` 或 `useThrottledValue`。 +每个框架适配器都提供建立在核心节流功能之上的钩子,以与框架的状态管理系统集成。每个框架都提供诸如 `createThrottler`、`useThrottledCallback`、`useThrottledState` 或 `useThrottledValue` 等钩子。 以下是一些示例: @@ -261,7 +240,7 @@ const handleUpdate = useThrottledCallback( // 用于响应式状态管理的基于状态的钩子 const [instantState, setInstantState] = useState(0) const [throttledValue] = useThrottledValue( - instantState, // 要节流的值 + instantState, // 需要节流的值 { wait: 200 } ) ``` diff --git a/docs/zh-hans/reference/classes/asyncdebouncer.md b/docs/zh-hans/reference/classes/asyncdebouncer.md index f63de251e..cecdb1d01 100644 --- a/docs/zh-hans/reference/classes/asyncdebouncer.md +++ b/docs/zh-hans/reference/classes/asyncdebouncer.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:02:12.708Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:42:47.783Z' id: AsyncDebouncer title: AsyncDebouncer --- @@ -9,7 +9,7 @@ title: AsyncDebouncer # Class: AsyncDebouncer\ -Defined in: [async-debouncer.ts:73](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L73) +Defined in: [async-debouncer.ts:77](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L77) A class that creates an async debounced function. @@ -20,17 +20,21 @@ or input changes where you only want to execute the handler after the events hav Unlike throttling which allows execution at regular intervals, debouncing prevents any execution until the function stops being called for the specified delay period. +Unlike the non-async Debouncer, this async version supports returning values from the debounced function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the debounced function. + ## Example ```ts const asyncDebouncer = new AsyncDebouncer(async (value: string) => { - await searchAPI(value); + const results = await searchAPI(value); + return results; // Return value is preserved }, { wait: 500 }); // Called on each keystroke but only executes after 500ms of no typing -inputElement.addEventListener('input', () => { - asyncDebouncer.maybeExecute(inputElement.value); -}); +// Returns the API response directly +const results = await asyncDebouncer.maybeExecute(inputElement.value); ``` ## Type Parameters @@ -45,7 +49,7 @@ inputElement.addEventListener('input', () => { new AsyncDebouncer(fn, initialOptions): AsyncDebouncer ``` -Defined in: [async-debouncer.ts:86](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L86) +Defined in: [async-debouncer.ts:90](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L90) #### Parameters @@ -69,7 +73,7 @@ Defined in: [async-debouncer.ts:86](https://github.com/TanStack/pacer/blob/main/ cancel(): void ``` -Defined in: [async-debouncer.ts:195](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L195) +Defined in: [async-debouncer.ts:199](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L199) Cancels any pending execution or aborts any execution in progress @@ -85,7 +89,7 @@ Cancels any pending execution or aborts any execution in progress getErrorCount(): number ``` -Defined in: [async-debouncer.ts:224](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L224) +Defined in: [async-debouncer.ts:228](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L228) Returns the number of times the function has errored @@ -101,7 +105,7 @@ Returns the number of times the function has errored getIsExecuting(): boolean ``` -Defined in: [async-debouncer.ts:238](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L238) +Defined in: [async-debouncer.ts:242](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L242) Returns `true` if there is currently an execution in progress @@ -117,7 +121,7 @@ Returns `true` if there is currently an execution in progress getIsPending(): boolean ``` -Defined in: [async-debouncer.ts:231](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L231) +Defined in: [async-debouncer.ts:235](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L235) Returns `true` if there is a pending execution queued up for trailing execution @@ -133,7 +137,7 @@ Returns `true` if there is a pending execution queued up for trailing execution getLastResult(): undefined | ReturnType ``` -Defined in: [async-debouncer.ts:203](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L203) +Defined in: [async-debouncer.ts:207](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L207) Returns the last result of the debounced function @@ -149,7 +153,7 @@ Returns the last result of the debounced function getOptions(): Required> ``` -Defined in: [async-debouncer.ts:112](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L112) +Defined in: [async-debouncer.ts:116](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L116) Returns the current debouncer options @@ -165,7 +169,7 @@ Returns the current debouncer options getSettleCount(): number ``` -Defined in: [async-debouncer.ts:217](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L217) +Defined in: [async-debouncer.ts:221](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L221) Returns the number of times the function has settled (completed or errored) @@ -181,7 +185,7 @@ Returns the number of times the function has settled (completed or errored) getSuccessCount(): number ``` -Defined in: [async-debouncer.ts:210](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L210) +Defined in: [async-debouncer.ts:214](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L214) Returns the number of times the function has been executed successfully @@ -197,7 +201,7 @@ Returns the number of times the function has been executed successfully maybeExecute(...args): Promise> ``` -Defined in: [async-debouncer.ts:120](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L120) +Defined in: [async-debouncer.ts:124](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L124) Attempts to execute the debounced function If a call is already in progress, it will be queued @@ -220,7 +224,7 @@ If a call is already in progress, it will be queued setOptions(newOptions): void ``` -Defined in: [async-debouncer.ts:100](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L100) +Defined in: [async-debouncer.ts:104](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L104) Updates the debouncer options Returns the new options state diff --git a/docs/zh-hans/reference/classes/asyncratelimiter.md b/docs/zh-hans/reference/classes/asyncratelimiter.md index 46ee1fb74..c87b2b57c 100644 --- a/docs/zh-hans/reference/classes/asyncratelimiter.md +++ b/docs/zh-hans/reference/classes/asyncratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:02:12.699Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:42:47.779Z' id: AsyncRateLimiter title: AsyncRateLimiter --- @@ -9,7 +9,7 @@ title: AsyncRateLimiter # Class: AsyncRateLimiter\ -Defined in: [async-rate-limiter.ts:76](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L76) +Defined in: [async-rate-limiter.ts:95](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L95) A class that creates an async rate-limited function. @@ -17,6 +17,16 @@ Rate limiting is a simple approach that allows a function to execute up to a lim then blocks all subsequent calls until the window passes. This can lead to "bursty" behavior where all executions happen immediately, followed by a complete block. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + +Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + For smoother execution patterns, consider using: - Throttling: Ensures consistent spacing between executions (e.g. max once per 200ms) - Debouncing: Waits for a pause in calls before executing (e.g. after 500ms of no calls) @@ -29,11 +39,12 @@ smoothing out frequent events, throttling or debouncing usually provide better u ```ts const rateLimiter = new AsyncRateLimiter( async (id: string) => await api.getData(id), - { limit: 5, window: 1000 } // 5 calls per second + { limit: 5, window: 1000, windowType: 'sliding' } // 5 calls per second with sliding window ); // Will execute immediately until limit reached, then block -await rateLimiter.maybeExecute('123'); +// Returns the API response directly +const data = await rateLimiter.maybeExecute('123'); ``` ## Type Parameters @@ -48,7 +59,7 @@ await rateLimiter.maybeExecute('123'); new AsyncRateLimiter(fn, initialOptions): AsyncRateLimiter ``` -Defined in: [async-rate-limiter.ts:85](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L85) +Defined in: [async-rate-limiter.ts:105](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L105) #### Parameters @@ -72,7 +83,7 @@ Defined in: [async-rate-limiter.ts:85](https://github.com/TanStack/pacer/blob/ma getErrorCount(): number ``` -Defined in: [async-rate-limiter.ts:209](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L209) +Defined in: [async-rate-limiter.ts:250](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L250) Returns the number of times the function has errored @@ -82,15 +93,33 @@ Returns the number of times the function has errored *** +### getIsExecuting() + +```ts +getIsExecuting(): boolean +``` + +Defined in: [async-rate-limiter.ts:264](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L264) + +Returns whether the function is currently executing + +#### Returns + +`boolean` + +*** + ### getMsUntilNextWindow() ```ts getMsUntilNextWindow(): number ``` -Defined in: [async-rate-limiter.ts:188](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L188) +Defined in: [async-rate-limiter.ts:225](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L225) Returns the number of milliseconds until the next execution will be possible +For fixed windows, this is the time until the current window resets +For sliding windows, this is the time until the oldest execution expires #### Returns @@ -104,7 +133,7 @@ Returns the number of milliseconds until the next execution will be possible getOptions(): Required> ``` -Defined in: [async-rate-limiter.ts:106](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L106) +Defined in: [async-rate-limiter.ts:126](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L126) Returns the current rate limiter options @@ -120,7 +149,7 @@ Returns the current rate limiter options getRejectionCount(): number ``` -Defined in: [async-rate-limiter.ts:216](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L216) +Defined in: [async-rate-limiter.ts:257](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L257) Returns the number of times the function has been rejected @@ -136,7 +165,7 @@ Returns the number of times the function has been rejected getRemainingInWindow(): number ``` -Defined in: [async-rate-limiter.ts:180](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L180) +Defined in: [async-rate-limiter.ts:215](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L215) Returns the number of remaining executions allowed in the current window @@ -152,7 +181,7 @@ Returns the number of remaining executions allowed in the current window getSettleCount(): number ``` -Defined in: [async-rate-limiter.ts:202](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L202) +Defined in: [async-rate-limiter.ts:243](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L243) Returns the number of times the function has been settled @@ -168,7 +197,7 @@ Returns the number of times the function has been settled getSuccessCount(): number ``` -Defined in: [async-rate-limiter.ts:195](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L195) +Defined in: [async-rate-limiter.ts:236](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L236) Returns the number of times the function has been executed @@ -184,7 +213,7 @@ Returns the number of times the function has been executed maybeExecute(...args): Promise> ``` -Defined in: [async-rate-limiter.ts:126](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L126) +Defined in: [async-rate-limiter.ts:146](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L146) Attempts to execute the rate-limited function if within the configured limits. Will reject execution if the number of calls in the current window exceeds the limit. @@ -220,7 +249,7 @@ await rateLimiter.maybeExecute('arg1', 'arg2'); // Rejected reset(): void ``` -Defined in: [async-rate-limiter.ts:223](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L223) +Defined in: [async-rate-limiter.ts:271](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L271) Resets the rate limiter state @@ -236,7 +265,7 @@ Resets the rate limiter state setOptions(newOptions): void ``` -Defined in: [async-rate-limiter.ts:99](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L99) +Defined in: [async-rate-limiter.ts:119](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L119) Updates the rate limiter options Returns the new options state diff --git a/docs/zh-hans/reference/classes/asyncthrottler.md b/docs/zh-hans/reference/classes/asyncthrottler.md index 136be007d..80e60fdb7 100644 --- a/docs/zh-hans/reference/classes/asyncthrottler.md +++ b/docs/zh-hans/reference/classes/asyncthrottler.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:02:12.695Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:42:47.775Z' id: AsyncThrottler title: AsyncThrottler --- @@ -9,7 +9,7 @@ title: AsyncThrottler # Class: AsyncThrottler\ -Defined in: [async-throttler.ts:76](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L76) +Defined in: [async-throttler.ts:80](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L80) A class that creates an async throttled function. @@ -17,6 +17,10 @@ Throttling limits how often a function can be executed, allowing only one execut Unlike debouncing which resets the delay timer on each call, throttling ensures the function executes at a regular interval regardless of how often it's called. +Unlike the non-async Throttler, this async version supports returning values from the throttled function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the throttled function. + This is useful for rate-limiting API calls, handling scroll/resize events, or any scenario where you want to ensure a maximum execution frequency. @@ -24,13 +28,13 @@ ensure a maximum execution frequency. ```ts const throttler = new AsyncThrottler(async (value: string) => { - await saveToAPI(value); + const result = await saveToAPI(value); + return result; // Return value is preserved }, { wait: 1000 }); // Will only execute once per second no matter how often called -inputElement.addEventListener('input', () => { - throttler.maybeExecute(inputElement.value); -}); +// Returns the API response directly +const result = await throttler.maybeExecute(inputElement.value); ``` ## Type Parameters @@ -45,7 +49,7 @@ inputElement.addEventListener('input', () => { new AsyncThrottler(fn, initialOptions): AsyncThrottler ``` -Defined in: [async-throttler.ts:89](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L89) +Defined in: [async-throttler.ts:93](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L93) #### Parameters @@ -69,7 +73,7 @@ Defined in: [async-throttler.ts:89](https://github.com/TanStack/pacer/blob/main/ cancel(): void ``` -Defined in: [async-throttler.ts:187](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L187) +Defined in: [async-throttler.ts:191](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L191) Cancels any pending execution or aborts any execution in progress @@ -85,7 +89,7 @@ Cancels any pending execution or aborts any execution in progress getErrorCount(): number ``` -Defined in: [async-throttler.ts:237](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L237) +Defined in: [async-throttler.ts:241](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L241) Returns the number of times the function has errored @@ -101,7 +105,7 @@ Returns the number of times the function has errored getIsExecuting(): boolean ``` -Defined in: [async-throttler.ts:251](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L251) +Defined in: [async-throttler.ts:255](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L255) Returns the current executing state @@ -117,7 +121,7 @@ Returns the current executing state getIsPending(): boolean ``` -Defined in: [async-throttler.ts:244](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L244) +Defined in: [async-throttler.ts:248](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L248) Returns the current pending state @@ -133,7 +137,7 @@ Returns the current pending state getLastExecutionTime(): number ``` -Defined in: [async-throttler.ts:202](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L202) +Defined in: [async-throttler.ts:206](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L206) Returns the last execution time @@ -149,7 +153,7 @@ Returns the last execution time getLastResult(): undefined | ReturnType ``` -Defined in: [async-throttler.ts:216](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L216) +Defined in: [async-throttler.ts:220](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L220) Returns the last result of the debounced function @@ -165,7 +169,7 @@ Returns the last result of the debounced function getNextExecutionTime(): number ``` -Defined in: [async-throttler.ts:209](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L209) +Defined in: [async-throttler.ts:213](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L213) Returns the next execution time @@ -181,7 +185,7 @@ Returns the next execution time getOptions(): Required> ``` -Defined in: [async-throttler.ts:115](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L115) +Defined in: [async-throttler.ts:119](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L119) Returns the current options @@ -197,7 +201,7 @@ Returns the current options getSettleCount(): number ``` -Defined in: [async-throttler.ts:230](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L230) +Defined in: [async-throttler.ts:234](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L234) Returns the number of times the function has settled (completed or errored) @@ -213,7 +217,7 @@ Returns the number of times the function has settled (completed or errored) getSuccessCount(): number ``` -Defined in: [async-throttler.ts:223](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L223) +Defined in: [async-throttler.ts:227](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L227) Returns the number of times the function has been executed successfully @@ -229,7 +233,7 @@ Returns the number of times the function has been executed successfully maybeExecute(...args): Promise> ``` -Defined in: [async-throttler.ts:123](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L123) +Defined in: [async-throttler.ts:127](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L127) Attempts to execute the throttled function If a call is already in progress, it may be blocked or queued depending on the `wait` option @@ -252,7 +256,7 @@ If a call is already in progress, it may be blocked or queued depending on the ` setOptions(newOptions): void ``` -Defined in: [async-throttler.ts:103](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L103) +Defined in: [async-throttler.ts:107](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L107) Updates the throttler options Returns the new options state diff --git a/docs/zh-hans/reference/classes/ratelimiter.md b/docs/zh-hans/reference/classes/ratelimiter.md index 79929e44b..f53d119e6 100644 --- a/docs/zh-hans/reference/classes/ratelimiter.md +++ b/docs/zh-hans/reference/classes/ratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:02:12.664Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:42:47.730Z' id: RateLimiter title: RateLimiter --- @@ -9,7 +9,7 @@ title: RateLimiter # Class: RateLimiter\ -Defined in: [rate-limiter.ts:63](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L63) +Defined in: [rate-limiter.ts:77](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L77) A class that creates a rate-limited function. @@ -17,6 +17,12 @@ Rate limiting is a simple approach that allows a function to execute up to a lim then blocks all subsequent calls until the window passes. This can lead to "bursty" behavior where all executions happen immediately, followed by a complete block. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns, consider using: - Throttling: Ensures consistent spacing between executions (e.g. max once per 200ms) - Debouncing: Waits for a pause in calls before executing (e.g. after 500ms of no calls) @@ -29,7 +35,7 @@ smoothing out frequent events, throttling or debouncing usually provide better u ```ts const rateLimiter = new RateLimiter( (id: string) => api.getData(id), - { limit: 5, window: 1000 } // 5 calls per second + { limit: 5, window: 1000, windowType: 'sliding' } // 5 calls per second with sliding window ); // Will execute immediately until limit reached, then block @@ -48,7 +54,7 @@ rateLimiter.maybeExecute('123'); new RateLimiter(fn, initialOptions): RateLimiter ``` -Defined in: [rate-limiter.ts:69](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L69) +Defined in: [rate-limiter.ts:83](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L83) #### Parameters @@ -72,7 +78,7 @@ Defined in: [rate-limiter.ts:69](https://github.com/TanStack/pacer/blob/main/pac getExecutionCount(): number ``` -Defined in: [rate-limiter.ts:149](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L149) +Defined in: [rate-limiter.ts:175](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L175) Returns the number of times the function has been executed @@ -88,7 +94,7 @@ Returns the number of times the function has been executed getMsUntilNextWindow(): number ``` -Defined in: [rate-limiter.ts:171](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L171) +Defined in: [rate-limiter.ts:197](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L197) Returns the number of milliseconds until the next execution will be possible @@ -104,7 +110,7 @@ Returns the number of milliseconds until the next execution will be possible getOptions(): Required> ``` -Defined in: [rate-limiter.ts:90](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L90) +Defined in: [rate-limiter.ts:104](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L104) Returns the current rate limiter options @@ -120,7 +126,7 @@ Returns the current rate limiter options getRejectionCount(): number ``` -Defined in: [rate-limiter.ts:156](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L156) +Defined in: [rate-limiter.ts:182](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L182) Returns the number of times the function has been rejected @@ -136,7 +142,7 @@ Returns the number of times the function has been rejected getRemainingInWindow(): number ``` -Defined in: [rate-limiter.ts:163](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L163) +Defined in: [rate-limiter.ts:189](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L189) Returns the number of remaining executions allowed in the current window @@ -152,7 +158,7 @@ Returns the number of remaining executions allowed in the current window maybeExecute(...args): boolean ``` -Defined in: [rate-limiter.ts:109](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L109) +Defined in: [rate-limiter.ts:123](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L123) Attempts to execute the rate-limited function if within the configured limits. Will reject execution if the number of calls in the current window exceeds the limit. @@ -187,7 +193,7 @@ rateLimiter.maybeExecute('arg1', 'arg2'); // false reset(): void ``` -Defined in: [rate-limiter.ts:179](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L179) +Defined in: [rate-limiter.ts:208](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L208) Resets the rate limiter state @@ -203,7 +209,7 @@ Resets the rate limiter state setOptions(newOptions): void ``` -Defined in: [rate-limiter.ts:83](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L83) +Defined in: [rate-limiter.ts:97](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L97) Updates the rate limiter options Returns the new options state diff --git a/docs/zh-hans/reference/functions/asyncdebounce.md b/docs/zh-hans/reference/functions/asyncdebounce.md index 459df92be..2c1df9e23 100644 --- a/docs/zh-hans/reference/functions/asyncdebounce.md +++ b/docs/zh-hans/reference/functions/asyncdebounce.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-04-24T02:14:56.000Z' -translation-updated-at: '2025-05-06T20:25:55.530Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:42:47.726Z' id: asyncDebounce title: asyncDebounce --- @@ -10,21 +10,23 @@ title: asyncDebounce # Function: asyncDebounce() ```ts -function asyncDebounce(fn, initialOptions): (...args) => Promise +function asyncDebounce(fn, initialOptions): (...args) => Promise> ``` -Defined in: [async-debouncer.ts:219](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L219) +Defined in: [async-debouncer.ts:268](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L268) Creates an async debounced function that delays execution until after a specified wait time. The debounced function will only execute once the wait period has elapsed without any new calls. If called again during the wait period, the timer resets and a new wait period begins. +Unlike the non-async Debouncer, this async version supports returning values from the debounced function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the debounced function. + ## Type Parameters • **TFn** *extends* [`AnyAsyncFunction`](../type-aliases/anyasyncfunction.md) -• **TArgs** *extends* `any`[] - ## Parameters ### fn @@ -33,7 +35,7 @@ If called again during the wait period, the timer resets and a new wait period b ### initialOptions -`Omit`\<[`AsyncDebouncerOptions`](../interfaces/asyncdebounceroptions.md)\<`TFn`, `TArgs`\>, `"enabled"`\> +`Omit`\<[`AsyncDebouncerOptions`](../interfaces/asyncdebounceroptions.md)\<`TFn`\>, `"enabled"`\> ## Returns @@ -46,21 +48,21 @@ If a call is already in progress, it will be queued #### args -...`TArgs` +...`Parameters`\<`TFn`\> ### Returns -`Promise`\<`void`\> +`Promise`\<`undefined` \| `ReturnType`\<`TFn`\>\> ## Example ```ts const debounced = asyncDebounce(async (value: string) => { - await saveToAPI(value); + const result = await saveToAPI(value); + return result; // Return value is preserved }, { wait: 1000 }); // Will only execute once, 1 second after the last call -await debounced("first"); // Cancelled -await debounced("second"); // Cancelled -await debounced("third"); // Executes after 1s +// Returns the API response directly +const result = await debounced("third"); ``` diff --git a/docs/zh-hans/reference/functions/asyncratelimit.md b/docs/zh-hans/reference/functions/asyncratelimit.md index 18334a111..b365b1dfb 100644 --- a/docs/zh-hans/reference/functions/asyncratelimit.md +++ b/docs/zh-hans/reference/functions/asyncratelimit.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:02:12.653Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:42:47.721Z' id: asyncRateLimit title: asyncRateLimit --- @@ -13,10 +13,20 @@ title: asyncRateLimit function asyncRateLimit(fn, initialOptions): (...args) => Promise> ``` -Defined in: [async-rate-limiter.ts:262](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L262) +Defined in: [async-rate-limiter.ts:322](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L322) Creates an async rate-limited function that will execute the provided function up to a maximum number of times within a time window. +Unlike the non-async rate limiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + Note that rate limiting is a simpler form of execution control compared to throttling or debouncing: - A rate limiter will allow all executions until the limit is reached, then block all subsequent calls until the window resets - A throttler ensures even spacing between executions, which can be better for consistent performance @@ -72,10 +82,11 @@ await rateLimiter.maybeExecute('arg1', 'arg2'); // Rejected ## Example ```ts -// Rate limit to 5 calls per minute +// Rate limit to 5 calls per minute with a sliding window const rateLimited = asyncRateLimit(makeApiCall, { limit: 5, window: 60000, + windowType: 'sliding', onReject: (rateLimiter) => { console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } @@ -83,7 +94,8 @@ const rateLimited = asyncRateLimit(makeApiCall, { // First 5 calls will execute immediately // Additional calls will be rejected until the minute window resets -await rateLimited(); +// Returns the API response directly +const result = await rateLimited(); // For more even execution, consider using throttle instead: const throttled = throttle(makeApiCall, { wait: 12000 }); // One call every 12 seconds diff --git a/docs/zh-hans/reference/functions/asyncthrottle.md b/docs/zh-hans/reference/functions/asyncthrottle.md index ed657061f..7aba08a6d 100644 --- a/docs/zh-hans/reference/functions/asyncthrottle.md +++ b/docs/zh-hans/reference/functions/asyncthrottle.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-04-24T02:14:56.000Z' -translation-updated-at: '2025-05-06T20:25:55.521Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:42:47.716Z' id: asyncThrottle title: asyncThrottle --- @@ -10,21 +10,23 @@ title: asyncThrottle # Function: asyncThrottle() ```ts -function asyncThrottle(fn, initialOptions): (...args) => Promise +function asyncThrottle(fn, initialOptions): (...args) => Promise> ``` -Defined in: [async-throttler.ts:223](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L223) +Defined in: [async-throttler.ts:281](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L281) Creates an async throttled function that limits how often the function can execute. The throttled function will execute at most once per wait period, even if called multiple times. If called while executing, it will wait until execution completes before scheduling the next call. +Unlike the non-async Throttler, this async version supports returning values from the throttled function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the throttled function. + ## Type Parameters • **TFn** *extends* [`AnyAsyncFunction`](../type-aliases/anyasyncfunction.md) -• **TArgs** *extends* `any`[] - ## Parameters ### fn @@ -33,7 +35,7 @@ If called while executing, it will wait until execution completes before schedul ### initialOptions -`Omit`\<[`AsyncThrottlerOptions`](../interfaces/asyncthrottleroptions.md)\<`TFn`, `TArgs`\>, `"enabled"`\> +`Omit`\<[`AsyncThrottlerOptions`](../interfaces/asyncthrottleroptions.md)\<`TFn`\>, `"enabled"`\> ## Returns @@ -46,20 +48,21 @@ If a call is already in progress, it may be blocked or queued depending on the ` #### args -...`TArgs` +...`Parameters`\<`TFn`\> ### Returns -`Promise`\<`void`\> +`Promise`\<`undefined` \| `ReturnType`\<`TFn`\>\> ## Example ```ts -const throttled = asyncThrottle(async () => { - await someAsyncOperation(); +const throttled = asyncThrottle(async (value: string) => { + const result = await saveToAPI(value); + return result; // Return value is preserved }, { wait: 1000 }); // This will execute at most once per second -await throttled(); -await throttled(); // Waits 1 second before executing +// Returns the API response directly +const result = await throttled(inputElement.value); ``` diff --git a/docs/zh-hans/reference/functions/ratelimit.md b/docs/zh-hans/reference/functions/ratelimit.md index b48c1ac78..4581bbfa9 100644 --- a/docs/zh-hans/reference/functions/ratelimit.md +++ b/docs/zh-hans/reference/functions/ratelimit.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:02:12.645Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:42:47.710Z' id: rateLimit title: rateLimit --- @@ -13,7 +13,7 @@ title: rateLimit function rateLimit(fn, initialOptions): (...args) => boolean ``` -Defined in: [rate-limiter.ts:216](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L216) +Defined in: [rate-limiter.ts:252](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L252) Creates a rate-limited function that will execute the provided function up to a maximum number of times within a time window. @@ -22,6 +22,12 @@ Note that rate limiting is a simpler form of execution control compared to throt - A throttler ensures even spacing between executions, which can be better for consistent performance - A debouncer collapses multiple calls into one, which is better for handling bursts of events +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + Consider using throttle() or debounce() if you need more intelligent execution control. Use rate limiting when you specifically need to enforce a hard limit on the number of executions within a time period. @@ -71,10 +77,11 @@ rateLimiter.maybeExecute('arg1', 'arg2'); // false ## Example ```ts -// Rate limit to 5 calls per minute +// Rate limit to 5 calls per minute with a sliding window const rateLimited = rateLimit(makeApiCall, { limit: 5, window: 60000, + windowType: 'sliding', onReject: (rateLimiter) => { console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/zh-hans/reference/interfaces/asyncratelimiteroptions.md b/docs/zh-hans/reference/interfaces/asyncratelimiteroptions.md index c733ca664..389729978 100644 --- a/docs/zh-hans/reference/interfaces/asyncratelimiteroptions.md +++ b/docs/zh-hans/reference/interfaces/asyncratelimiteroptions.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:02:12.624Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:42:47.705Z' id: AsyncRateLimiterOptions title: AsyncRateLimiterOptions --- @@ -149,3 +149,18 @@ window: number; Defined in: [async-rate-limiter.ts:38](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L38) Time window in milliseconds within which the limit applies + +*** + +### windowType? + +```ts +optional windowType: "fixed" | "sliding"; +``` + +Defined in: [async-rate-limiter.ts:45](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L45) + +Type of window to use for rate limiting +- 'fixed': Uses a fixed window that resets after the window period +- 'sliding': Uses a sliding window that allows executions as old ones expire +Defaults to 'fixed' diff --git a/docs/zh-hans/reference/interfaces/ratelimiteroptions.md b/docs/zh-hans/reference/interfaces/ratelimiteroptions.md index 3a9abd4e7..54dce77c8 100644 --- a/docs/zh-hans/reference/interfaces/ratelimiteroptions.md +++ b/docs/zh-hans/reference/interfaces/ratelimiteroptions.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:02:12.595Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:42:47.697Z' id: RateLimiterOptions title: RateLimiterOptions --- @@ -97,3 +97,18 @@ window: number; Defined in: [rate-limiter.ts:27](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L27) Time window in milliseconds within which the limit applies + +*** + +### windowType? + +```ts +optional windowType: "fixed" | "sliding"; +``` + +Defined in: [rate-limiter.ts:34](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L34) + +Type of window to use for rate limiting +- 'fixed': Uses a fixed window that resets after the window period +- 'sliding': Uses a sliding window that allows executions as old ones expire +Defaults to 'fixed' diff --git a/docs/zh-hant/framework/react/reference/functions/useasyncratelimiter.md b/docs/zh-hant/framework/react/reference/functions/useasyncratelimiter.md index 46036c1d5..acd488a6f 100644 --- a/docs/zh-hant/framework/react/reference/functions/useasyncratelimiter.md +++ b/docs/zh-hant/framework/react/reference/functions/useasyncratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:04:17.833Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:45:08.704Z' id: useAsyncRateLimiter title: useAsyncRateLimiter --- @@ -13,7 +13,7 @@ title: useAsyncRateLimiter function useAsyncRateLimiter(fn, options): AsyncRateLimiter ``` -Defined in: [react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts:43](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts#L43) +Defined in: [react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts:54](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts#L54) A low-level React hook that creates an `AsyncRateLimiter` instance to limit how many times an async function can execute within a time window. @@ -24,6 +24,16 @@ Rate limiting allows an async function to execute up to a specified limit within then blocks subsequent calls until the window passes. This is useful for respecting API rate limits, managing resource constraints, or controlling bursts of async operations. +Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + ## Type Parameters • **TFn** *extends* `AnyAsyncFunction` @@ -45,21 +55,22 @@ managing resource constraints, or controlling bursts of async operations. ## Example ```tsx -// Basic API call rate limiting +// Basic API call rate limiting with return value const { maybeExecute } = useAsyncRateLimiter( async (id: string) => { const data = await api.fetchData(id); - return data; + return data; // Return value is preserved }, { limit: 5, window: 1000 } // 5 calls per second ); -// With state management +// With state management and return value const [data, setData] = useState(null); const { maybeExecute } = useAsyncRateLimiter( async (query) => { const result = await searchAPI(query); setData(result); + return result; // Return value can be used by the caller }, { limit: 10, diff --git a/docs/zh-hant/framework/react/reference/functions/useratelimitedcallback.md b/docs/zh-hant/framework/react/reference/functions/useratelimitedcallback.md index 10367c9c9..d421be9bf 100644 --- a/docs/zh-hant/framework/react/reference/functions/useratelimitedcallback.md +++ b/docs/zh-hant/framework/react/reference/functions/useratelimitedcallback.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-04-24T02:14:56.000Z' -translation-updated-at: '2025-05-06T20:27:49.612Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:45:08.698Z' id: useRateLimitedCallback title: useRateLimitedCallback --- @@ -13,7 +13,7 @@ title: useRateLimitedCallback function useRateLimitedCallback(fn, options): (...args) => boolean ``` -Defined in: [rate-limiter/useRateLimitedCallback.ts:52](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedCallback.ts#L52) +Defined in: [react-pacer/src/rate-limiter/useRateLimitedCallback.ts:59](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedCallback.ts#L59) A React hook that creates a rate-limited version of a callback function. This hook is essentially a wrapper around the basic `rateLimiter` function @@ -26,6 +26,12 @@ or debouncing, it does not attempt to space out or intelligently collapse calls. This can lead to bursts of rapid executions followed by periods where all calls are blocked. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns, consider: - useThrottledCallback: When you want consistent spacing between executions (e.g. UI updates) - useDebouncedCallback: When you want to collapse rapid calls into a single execution (e.g. search input) @@ -57,7 +63,7 @@ Consider using the `useRateLimiter` hook instead. ### options -`RateLimiterOptions`\<`TFn`, `TArgs`\> +`RateLimiterOptions`\<`TFn`\> ## Returns @@ -76,7 +82,7 @@ Consider using the `useRateLimiter` hook instead. ## Example ```tsx -// Rate limit API calls to maximum 5 calls per minute +// Rate limit API calls to maximum 5 calls per minute with a sliding window const makeApiCall = useRateLimitedCallback( (data: ApiData) => { return fetch('/api/endpoint', { method: 'POST', body: JSON.stringify(data) }); @@ -84,6 +90,7 @@ const makeApiCall = useRateLimitedCallback( { limit: 5, window: 60000, // 1 minute + windowType: 'sliding', onReject: () => { console.warn('API rate limit reached. Please wait before trying again.'); } diff --git a/docs/zh-hant/framework/react/reference/functions/useratelimitedstate.md b/docs/zh-hant/framework/react/reference/functions/useratelimitedstate.md index 297639a6d..71b73ea24 100644 --- a/docs/zh-hant/framework/react/reference/functions/useratelimitedstate.md +++ b/docs/zh-hant/framework/react/reference/functions/useratelimitedstate.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:04:17.796Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:45:08.693Z' id: useRateLimitedState title: useRateLimitedState --- @@ -13,7 +13,7 @@ title: useRateLimitedState function useRateLimitedState(value, options): [TValue, Dispatch>, RateLimiter>>] ``` -Defined in: [react-pacer/src/rate-limiter/useRateLimitedState.ts:59](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedState.ts#L59) +Defined in: [react-pacer/src/rate-limiter/useRateLimitedState.ts:66](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedState.ts#L66) A React hook that creates a rate-limited state value that enforces a hard limit on state updates within a time window. This hook combines React's useState with rate limiting functionality to provide controlled state updates. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - useThrottledState: When you want consistent spacing between updates (e.g. UI changes) - useDebouncedState: When you want to collapse rapid updates into a single update (e.g. search input) @@ -57,16 +63,18 @@ consider using the lower-level useRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update state at most 5 times per minute +// Basic rate limiting - update state at most 5 times per minute with a sliding window const [value, setValue, rateLimiter] = useRateLimitedState(0, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); -// With rejection callback +// With rejection callback and fixed window const [value, setValue] = useRateLimitedState(0, { limit: 3, window: 5000, + windowType: 'fixed', onReject: (rateLimiter) => { alert(`Rate limit reached. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/zh-hant/framework/react/reference/functions/useratelimitedvalue.md b/docs/zh-hant/framework/react/reference/functions/useratelimitedvalue.md index 8207aa18d..a03f68a70 100644 --- a/docs/zh-hant/framework/react/reference/functions/useratelimitedvalue.md +++ b/docs/zh-hant/framework/react/reference/functions/useratelimitedvalue.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:04:17.792Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:45:08.689Z' id: useRateLimitedValue title: useRateLimitedValue --- @@ -13,7 +13,7 @@ title: useRateLimitedValue function useRateLimitedValue(value, options): [TValue, RateLimiter>>] ``` -Defined in: [react-pacer/src/rate-limiter/useRateLimitedValue.ts:47](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedValue.ts#L47) +Defined in: [react-pacer/src/rate-limiter/useRateLimitedValue.ts:55](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedValue.ts#L55) A high-level React hook that creates a rate-limited version of a value that updates at most a certain number of times within a time window. This hook uses React's useState internally to manage the rate-limited state. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - useThrottledValue: When you want consistent spacing between updates (e.g. UI changes) - useDebouncedValue: When you want to collapse rapid updates into a single update (e.g. search input) @@ -56,16 +62,18 @@ consider using the lower-level useRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update at most 5 times per minute +// Basic rate limiting - update at most 5 times per minute with a sliding window const [rateLimitedValue, rateLimiter] = useRateLimitedValue(rawValue, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); -// With rejection callback +// With rejection callback and fixed window const [rateLimitedValue, rateLimiter] = useRateLimitedValue(rawValue, { limit: 3, window: 5000, + windowType: 'fixed', onReject: (rateLimiter) => { console.log(`Update rejected. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/zh-hant/framework/react/reference/functions/useratelimiter.md b/docs/zh-hant/framework/react/reference/functions/useratelimiter.md index 936e574d0..692739c98 100644 --- a/docs/zh-hant/framework/react/reference/functions/useratelimiter.md +++ b/docs/zh-hant/framework/react/reference/functions/useratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:04:17.787Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:45:08.684Z' id: useRateLimiter title: useRateLimiter --- @@ -13,7 +13,7 @@ title: useRateLimiter function useRateLimiter(fn, options): RateLimiter ``` -Defined in: [react-pacer/src/rate-limiter/useRateLimiter.ts:48](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimiter.ts#L48) +Defined in: [react-pacer/src/rate-limiter/useRateLimiter.ts:55](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimiter.ts#L55) A low-level React hook that creates a `RateLimiter` instance to enforce rate limits on function execution. @@ -24,6 +24,12 @@ Rate limiting is a simple "hard limit" approach that allows executions until a m a time window, then blocks all subsequent calls until the window resets. Unlike throttling or debouncing, it does not attempt to space out or collapse executions intelligently. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns: - Use throttling when you want consistent spacing between executions (e.g. UI updates) - Use debouncing when you want to collapse rapid-fire events (e.g. search input) @@ -57,10 +63,11 @@ The hook returns an object containing: ## Example ```tsx -// Basic rate limiting - max 5 calls per minute +// Basic rate limiting - max 5 calls per minute with a sliding window const { maybeExecute } = useRateLimiter(apiCall, { limit: 5, window: 60000, + windowType: 'sliding', }); // Monitor rate limit status diff --git a/docs/zh-hant/framework/solid/reference/functions/createasyncratelimiter.md b/docs/zh-hant/framework/solid/reference/functions/createasyncratelimiter.md index 15a9764b2..e03a3935e 100644 --- a/docs/zh-hant/framework/solid/reference/functions/createasyncratelimiter.md +++ b/docs/zh-hant/framework/solid/reference/functions/createasyncratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:04:17.760Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:45:08.677Z' id: createAsyncRateLimiter title: createAsyncRateLimiter --- @@ -13,7 +13,7 @@ title: createAsyncRateLimiter function createAsyncRateLimiter(fn, initialOptions): SolidAsyncRateLimiter ``` -Defined in: [async-rate-limiter/createAsyncRateLimiter.ts:62](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L62) +Defined in: [async-rate-limiter/createAsyncRateLimiter.ts:73](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L73) A low-level Solid hook that creates an `AsyncRateLimiter` instance to limit how many times an async function can execute within a time window. @@ -24,6 +24,16 @@ Rate limiting allows an async function to execute up to a specified limit within then blocks subsequent calls until the window passes. This is useful for respecting API rate limits, managing resource constraints, or controlling bursts of async operations. +Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + ## Type Parameters • **TFn** *extends* `AnyAsyncFunction` @@ -45,21 +55,22 @@ managing resource constraints, or controlling bursts of async operations. ## Example ```tsx -// Basic API call rate limiting +// Basic API call rate limiting with return value const { maybeExecute } = createAsyncRateLimiter( async (id: string) => { const data = await api.fetchData(id); - return data; + return data; // Return value is preserved }, { limit: 5, window: 1000 } // 5 calls per second ); -// With state management +// With state management and return value const [data, setData] = createSignal(null); const { maybeExecute } = createAsyncRateLimiter( async (query) => { const result = await searchAPI(query); setData(result); + return result; // Return value can be used by the caller }, { limit: 10, diff --git a/docs/zh-hant/framework/solid/reference/functions/createratelimitedsignal.md b/docs/zh-hant/framework/solid/reference/functions/createratelimitedsignal.md index 96c5e5d8f..abae34e8c 100644 --- a/docs/zh-hant/framework/solid/reference/functions/createratelimitedsignal.md +++ b/docs/zh-hant/framework/solid/reference/functions/createratelimitedsignal.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:04:17.734Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:45:08.673Z' id: createRateLimitedSignal title: createRateLimitedSignal --- @@ -13,7 +13,7 @@ title: createRateLimitedSignal function createRateLimitedSignal(value, initialOptions): [Accessor, Setter, SolidRateLimiter>] ``` -Defined in: [rate-limiter/createRateLimitedSignal.ts:57](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedSignal.ts#L57) +Defined in: [rate-limiter/createRateLimitedSignal.ts:65](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedSignal.ts#L65) A Solid hook that creates a rate-limited state value that enforces a hard limit on state updates within a time window. This hook combines Solid's createSignal with rate limiting functionality to provide controlled state updates. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - createThrottledSignal: When you want consistent spacing between updates (e.g. UI changes) - createDebouncedSignal: When you want to collapse rapid updates into a single update (e.g. search input) @@ -57,16 +63,18 @@ consider using the lower-level createRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update state at most 5 times per minute +// Basic rate limiting - update state at most 5 times per minute with a sliding window const [value, setValue, rateLimiter] = createRateLimitedSignal(0, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); -// With rejection callback +// With rejection callback and fixed window const [value, setValue] = createRateLimitedSignal(0, { limit: 3, window: 5000, + windowType: 'fixed', onReject: (rateLimiter) => { alert(`Rate limit reached. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/zh-hant/framework/solid/reference/functions/createratelimitedvalue.md b/docs/zh-hant/framework/solid/reference/functions/createratelimitedvalue.md index baaeee526..90f6dba28 100644 --- a/docs/zh-hant/framework/solid/reference/functions/createratelimitedvalue.md +++ b/docs/zh-hant/framework/solid/reference/functions/createratelimitedvalue.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:04:17.729Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:45:08.669Z' id: createRateLimitedValue title: createRateLimitedValue --- @@ -13,7 +13,7 @@ title: createRateLimitedValue function createRateLimitedValue(value, initialOptions): [Accessor, SolidRateLimiter>] ``` -Defined in: [rate-limiter/createRateLimitedValue.ts:43](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedValue.ts#L43) +Defined in: [rate-limiter/createRateLimitedValue.ts:50](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedValue.ts#L50) A high-level Solid hook that creates a rate-limited version of a value that updates at most a certain number of times within a time window. This hook uses Solid's createSignal internally to manage the rate-limited state. @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All updates within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows updates as old ones expire. This provides a more + consistent rate of updates over time. + For smoother update patterns, consider: - createThrottledValue: When you want consistent spacing between updates (e.g. UI changes) - createDebouncedValue: When you want to collapse rapid updates into a single update (e.g. search input) @@ -56,10 +62,11 @@ consider using the lower-level createRateLimiter hook instead. ## Example ```tsx -// Basic rate limiting - update at most 5 times per minute +// Basic rate limiting - update at most 5 times per minute with a sliding window const [rateLimitedValue, rateLimiter] = createRateLimitedValue(rawValue, { limit: 5, - window: 60000 + window: 60000, + windowType: 'sliding' }); // Use the rate-limited value diff --git a/docs/zh-hant/framework/solid/reference/functions/createratelimiter.md b/docs/zh-hant/framework/solid/reference/functions/createratelimiter.md index 30844e8b0..f9c41f837 100644 --- a/docs/zh-hant/framework/solid/reference/functions/createratelimiter.md +++ b/docs/zh-hant/framework/solid/reference/functions/createratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:04:17.725Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:45:08.661Z' id: createRateLimiter title: createRateLimiter --- @@ -13,7 +13,7 @@ title: createRateLimiter function createRateLimiter(fn, initialOptions): SolidRateLimiter ``` -Defined in: [rate-limiter/createRateLimiter.ts:61](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts#L61) +Defined in: [rate-limiter/createRateLimiter.ts:68](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts#L68) A low-level Solid hook that creates a `RateLimiter` instance to enforce rate limits on function execution. @@ -24,6 +24,12 @@ Rate limiting is a simple "hard limit" approach that allows executions until a m a time window, then blocks all subsequent calls until the window resets. Unlike throttling or debouncing, it does not attempt to space out or collapse executions intelligently. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns: - Use throttling when you want consistent spacing between executions (e.g. UI updates) - Use debouncing when you want to collapse rapid-fire events (e.g. search input) @@ -50,10 +56,11 @@ For smoother execution patterns: ## Example ```tsx -// Basic rate limiting - max 5 calls per minute +// Basic rate limiting - max 5 calls per minute with a sliding window const rateLimiter = createRateLimiter(apiCall, { limit: 5, window: 60000, + windowType: 'sliding' }); // Monitor rate limit status diff --git a/docs/zh-hant/guides/debouncing.md b/docs/zh-hant/guides/debouncing.md index 51e244e2e..b969eee2b 100644 --- a/docs/zh-hant/guides/debouncing.md +++ b/docs/zh-hant/guides/debouncing.md @@ -1,14 +1,16 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:06:21.580Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:47:16.351Z' title: 防抖指南 id: debouncing --- -速率限制 (Rate Limiting)、節流 (Throttling) 與防抖 (Debouncing) 是三種控制函數執行頻率的不同方法。每種技術都以不同的方式阻擋執行,使其成為「有損」的 — 意味著當函數被要求過於頻繁執行時,某些呼叫將不會被執行。了解何時使用每種方法對於構建高效能且可靠的應用程式至關重要。本指南將涵蓋 TanStack Pacer 的防抖概念。 +# 防抖 (Debouncing) 指南 + +速率限制 (Rate Limiting)、節流 (Throttling) 和防抖 (Debouncing) 是控制函數執行頻率的三種不同方法。每種技術以不同方式阻擋執行,使它們成為「有損」的 — 這意味當函數被要求過於頻繁執行時,某些呼叫將不會執行。了解何時使用每種方法對於構建高效能且可靠的應用程式至關重要。本指南將涵蓋 TanStack Pacer 的防抖概念。 ## 防抖概念 -防抖是一種技術,它會延遲函數的執行,直到指定的不活動時間過去。與速率限制 (允許在限制內爆發性執行) 或節流 (確保執行間隔均勻) 不同,防抖會將多次快速函數呼叫合併為單一執行,且僅在呼叫停止後才會發生。這使得防抖非常適合處理事件爆發的情況,當你只關心活動結束後的最終狀態時。 +防抖是一種技術,它延遲函數的執行,直到指定的不活動時間過去。與允許執行突發但有限制的速率限制不同,也不同於確保均勻間隔執行的節流,防抖將多次快速函數呼叫合併為單一執行,僅在呼叫停止後發生。這使得防抖非常適合處理突發事件,其中您只關心活動停止後的最終狀態。 ### 防抖視覺化 @@ -18,34 +20,34 @@ id: debouncing 呼叫: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ 已執行: ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ⏳ -> ✅ ❌ ⏳ -> ✅ [=================================================================] - ^ 在此處執行 - 無呼叫 3 個刻度後 + ^ 在此處執行,在 + 無呼叫的 3 個刻度後 - [呼叫爆發] [更多呼叫] [等待] [新爆發] + [呼叫突發] [更多呼叫] [等待] [新突發] 無執行 重置計時器 [延遲執行] [等待] [延遲執行] ``` ### 何時使用防抖 -當你想在採取行動前等待活動「暫停」時,防抖特別有效。這使其非常適合處理使用者輸入或其他快速觸發的事件,當你只關心最終狀態時。 +當您想在採取行動前等待活動「暫停」時,防抖特別有效。這使其非常適合處理使用者輸入或其他快速觸發的事件,其中您只關心最終狀態。 -常見使用情境包括: -- 搜尋輸入欄位,當你想等待使用者完成輸入時 -- 表單驗證,不應在每次按鍵時執行 -- 視窗大小調整計算,這些計算成本高昂 +常見使用案例包括: +- 搜尋輸入欄位,您希望等待使用者完成輸入 +- 不應在每次按鍵時運行的表單驗證 +- 計算成本高昂的視窗大小調整計算 - 編輯內容時自動儲存草稿 - 僅在使用者活動停止後才應發生的 API 呼叫 -- 任何你只關心快速變化後最終值的情境 +- 任何您只關心快速變化後最終值的場景 ### 何時不使用防抖 防抖可能不是最佳選擇的情況: -- 你需要保證在特定時間段內執行 (改用 [節流](../guides/throttling)) -- 你無法承受錯過任何執行 (改用 [排隊](../guides/queueing)) +- 您需要在特定時間段內保證執行(改用[節流](../guides/throttling)) +- 您不能承受錯過任何執行(改用[排隊](../guides/queueing)) ## TanStack Pacer 中的防抖 -TanStack Pacer 分別透過 `Debouncer` 和 `AsyncDebouncer` 類別 (及其對應的 `debounce` 和 `asyncDebounce` 函數) 提供同步和非同步防抖。 +TanStack Pacer 分別透過 `Debouncer` 和 `AsyncDebouncer` 類別(及其對應的 `debounce` 和 `asyncDebounce` 函數)提供同步和非同步防抖。 ### 使用 `debounce` 的基本用法 @@ -69,7 +71,7 @@ searchInput.addEventListener('input', (e) => { ### 使用 `Debouncer` 類別的高級用法 -為了更精確控制防抖行為,你可以直接使用 `Debouncer` 類別: +為了更精確控制防抖行為,您可以直接使用 `Debouncer` 類別: ```ts import { Debouncer } from '@tanstack/pacer' @@ -79,31 +81,31 @@ const searchDebouncer = new Debouncer( { wait: 500 } ) -// 獲取當前狀態資訊 -console.log(searchDebouncer.getExecutionCount()) // 成功執行次數 -console.log(searchDebouncer.getIsPending()) // 是否有呼叫待處理 +// 獲取當前狀態的資訊 +console.log(searchDebouncer.getExecutionCount()) // 成功執行的次數 +console.log(searchDebouncer.getIsPending()) // 是否有呼叫正在等待中 // 動態更新選項 searchDebouncer.setOptions({ wait: 1000 }) // 增加等待時間 -// 取消待處理的執行 +// 取消等待中的執行 searchDebouncer.cancel() ``` -### 前緣與後緣執行 +### 前緣和後緣執行 同步防抖器支援前緣和後緣執行: ```ts const debouncedFn = debounce(fn, { wait: 500, - leading: true, // 第一次呼叫時立即執行 - trailing: true, // 等待期後執行 + leading: true, // 在第一次呼叫時執行 + trailing: true, // 在等待期後執行 }) ``` - `leading: true` - 函數在第一次呼叫時立即執行 -- `leading: false` (預設) - 第一次呼叫開始等待計時器 +- `leading: false` (預設) - 第一次呼叫啟動等待計時器 - `trailing: true` (預設) - 函數在等待期後執行 - `trailing: false` - 等待期後不執行 @@ -114,28 +116,28 @@ const debouncedFn = debounce(fn, { ### 最大等待時間 -TanStack Pacer 防抖器特意不像其他防抖函式庫那樣提供 `maxWait` 選項。如果你需要讓執行在更分散的時間段內運行,請考慮改用 [節流](../guides/throttling) 技術。 +TanStack Pacer 防抖器特意不像其他防抖庫那樣擁有 `maxWait` 選項。如果您需要讓執行在更分散的時間段內運行,請考慮改用[節流](../guides/throttling)技術。 ### 啟用/停用 -`Debouncer` 類別支援透過 `enabled` 選項啟用/停用。使用 `setOptions` 方法,你可以隨時啟用/停用防抖器: +`Debouncer` 類別透過 `enabled` 選項支援啟用/停用。使用 `setOptions` 方法,您可以隨時啟用/停用防抖器: ```ts const debouncer = new Debouncer(fn, { wait: 500, enabled: false }) // 預設停用 debouncer.setOptions({ enabled: true }) // 隨時啟用 ``` -如果你使用的是框架適配器,其中防抖器選項是響應式的,你可以將 `enabled` 選項設置為條件值以動態啟用/停用防抖器: +如果您使用的是防抖器選項具有響應性的框架適配器,您可以將 `enabled` 選項設置為條件值以動態啟用/停用防抖器: ```ts // React 範例 const debouncer = useDebouncer( setSearch, - { wait: 500, enabled: searchInput.value.length > 3 } // 根據輸入長度啟用/停用 IF 使用支援響應式選項的框架適配器 + { wait: 500, enabled: searchInput.value.length > 3 } // 根據輸入長度啟用/停用(如果使用支援響應式選項的框架適配器) ) ``` -然而,如果你使用的是 `debounce` 函數或直接使用 `Debouncer` 類別,則必須使用 `setOptions` 方法來更改 `enabled` 選項,因為傳遞的選項實際上會傳遞給 `Debouncer` 類別的建構函數。 +但是,如果您使用的是 `debounce` 函數或直接使用 `Debouncer` 類別,則必須使用 `setOptions` 方法來更改 `enabled` 選項,因為傳遞的選項實際上是傳遞給 `Debouncer` 類別的建構函數。 ```ts // Solid 範例 @@ -147,7 +149,7 @@ createEffect(() => { ### 回呼選項 -同步和非同步防抖器都支援回呼選項,以處理防抖生命週期的不同方面: +同步和非同步防抖器都支援回呼選項以處理防抖生命週期的不同方面: #### 同步防抖器回呼 @@ -157,7 +159,7 @@ createEffect(() => { const debouncer = new Debouncer(fn, { wait: 500, onExecute: (debouncer) => { - // 每次成功執行後呼叫 + // 在每次成功執行後呼叫 console.log('函數已執行', debouncer.getExecutionCount()) } }) @@ -167,7 +169,7 @@ const debouncer = new Debouncer(fn, { #### 非同步防抖器回呼 -非同步 `AsyncDebouncer` 的回呼集與同步版本不同。 +非同步 `AsyncDebouncer` 與同步版本相比具有一組不同的回呼。 ```ts const asyncDebouncer = new AsyncDebouncer(async (value) => { @@ -175,11 +177,11 @@ const asyncDebouncer = new AsyncDebouncer(async (value) => { }, { wait: 500, onSuccess: (result, debouncer) => { - // 每次成功執行後呼叫 + // 在每次成功執行後呼叫 console.log('非同步函數已執行', debouncer.getSuccessCount()) }, onSettled: (debouncer) => { - // 每次執行嘗試後呼叫 + // 在每次執行嘗試後呼叫 console.log('非同步函數已結算', debouncer.getSettledCount()) }, onError: (error) => { @@ -193,33 +195,27 @@ const asyncDebouncer = new AsyncDebouncer(async (value) => { ### 非同步防抖 -非同步防抖器提供了一種強大的方式來處理非同步操作與防抖,相比同步版本提供了幾個關鍵優勢。雖然同步防抖器非常適合 UI 事件和即時反饋,但非同步版本專門設計用於處理 API 呼叫、資料庫操作和其他非同步任務。 +非同步防抖器提供了一種強大的方式來處理非同步操作與防抖,相比同步版本具有幾個關鍵優勢。雖然同步防抖器非常適合 UI 事件和即時反饋,但非同步版本專門設計用於處理 API 呼叫、數據庫操作和其他非同步任務。 -#### 與同步防抖的主要差異 +#### 與同步防抖的主要區別 1. **返回值處理** -與返回 void 的同步防抖器不同,非同步版本允許你捕獲並使用防抖函數的返回值。這在需要處理 API 呼叫或其他非同步操作的結果時特別有用。`maybeExecute` 方法返回一個 Promise,該 Promise 解析為函數的返回值,允許你等待結果並適當處理。 - -2. **增強的回呼系統** -非同步防抖器提供比同步版本的單一 `onExecute` 回呼更複雜的回呼系統。此系統包括: -- `onSuccess`:當非同步函數成功完成時呼叫,提供結果和防抖器實例 -- `onError`:當非同步函數拋出錯誤時呼叫,提供錯誤和防抖器實例 -- `onSettled`:在每次執行嘗試後呼叫,無論成功或失敗 +與返回 void 的同步防抖器不同,非同步版本允許您捕獲和使用防抖函數的返回值。這在您需要使用 API 呼叫或其他非同步操作的結果時特別有用。`maybeExecute` 方法返回一個 Promise,該 Promise 解析為函數的返回值,允許您等待結果並適當處理。 -3. **執行追蹤** -非同步防抖器透過多種方法提供全面的執行追蹤: -- `getSuccessCount()`:成功執行次數 -- `getErrorCount()`:失敗執行次數 -- `getSettledCount()`:已結算的執行總數 (成功 + 失敗) +2. **不同的回呼** +`AsyncDebouncer` 支援以下回呼,而不僅僅是同步版本中的 `onExecute`: +- `onSuccess`:在每次成功執行後呼叫,提供防抖器實例 +- `onSettled`:在每次執行後呼叫,提供防抖器實例 +- `onError`:如果非同步函數拋出錯誤則呼叫,提供錯誤和防抖器實例 -4. **順序執行** -非同步防抖器確保後續執行等待前一次呼叫完成後才開始。這防止了執行順序錯亂,並保證每次呼叫處理的都是最新的資料。這在處理依賴於先前呼叫結果的操作或當保持資料一致性至關重要時特別重要。 +3. **順序執行** +由於防抖器的 `maybeExecute` 方法返回一個 Promise,您可以選擇在開始下一次執行前等待每次執行。這讓您可以控制執行順序並確保每次呼叫處理最新的數據。這在處理依賴先前呼叫結果的操作或維護數據一致性至關重要時特別有用。 -例如,如果你正在更新使用者個人資料,然後立即獲取其更新後的資料,非同步防抖器將確保獲取操作等待更新完成,防止可能獲取過時資料的競態條件。 +例如,如果您正在更新使用者的個人資料並立即獲取其更新後的數據,您可以在開始獲取前等待更新操作: #### 基本用法範例 -這是一個基本範例,展示如何將非同步防抖器用於搜尋操作: +以下是一個基本範例,展示如何使用非同步防抖器進行搜尋操作: ```ts const debouncedSearch = asyncDebounce( @@ -242,22 +238,9 @@ const debouncedSearch = asyncDebounce( const results = await debouncedSearch('query') ``` -#### 高級模式 - -非同步防抖器可以與各種模式結合以解決複雜問題: - -1. **狀態管理整合** -當將非同步防抖器與狀態管理系統 (如 React 的 useState 或 Solid 的 createSignal) 一起使用時,你可以創建強大的模式來處理載入狀態、錯誤狀態和資料更新。防抖器的回呼提供了根據操作成功或失敗更新 UI 狀態的完美鉤點。 - -2. **競態條件預防** -單次飛行突變模式自然防止了許多情境下的競態條件。當應用程式的多個部分同時嘗試更新同一資源時,防抖器確保只有最近的更新實際發生,同時仍向所有呼叫者提供結果。 - -3. **錯誤恢復** -非同步防抖器的錯誤處理能力使其非常適合實現重試邏輯和錯誤恢復模式。你可以使用 `onError` 回呼來實現自定義錯誤處理策略,例如指數退避或後備機制。 - ### 框架適配器 -每個框架適配器都提供建立在核心防抖功能之上的鉤子,以與框架的狀態管理系統整合。每個框架都有可用的鉤子,如 `createDebouncer`、`useDebouncedCallback`、`useDebouncedState` 或 `useDebouncedValue`。 +每個框架適配器都提供建立在核心防抖功能之上的鉤子,以與框架的狀態管理系統集成。每個框架都有可用的鉤子,如 `createDebouncer`、`useDebouncedCallback`、`useDebouncedState` 或 `useDebouncedValue`。 以下是一些範例: diff --git a/docs/zh-hant/guides/rate-limiting.md b/docs/zh-hant/guides/rate-limiting.md index 5f7ffe97c..22c2a2d09 100644 --- a/docs/zh-hant/guides/rate-limiting.md +++ b/docs/zh-hant/guides/rate-limiting.md @@ -1,56 +1,87 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:06:28.311Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:47:45.610Z' title: 速率限制指南 id: rate-limiting --- # 速率限制指南 (Rate Limiting Guide) -速率限制 (Rate Limiting)、節流 (Throttling) 和防抖 (Debouncing) 是三種控制函數執行頻率的不同方法。每種技術以不同的方式阻擋執行,使它們具有「損耗性」— 這意味著當函數被要求過於頻繁執行時,某些呼叫將不會執行。了解何時使用每種方法對於構建高效能且可靠的應用程式至關重要。本指南將介紹 TanStack Pacer 的速率限制概念。 +TanStack Pacer 是一個專注於提供高品質工具函式庫,用於控制應用程式中函式執行時機。雖然其他地方也有類似工具,但我們的目標是確保所有重要細節都正確無誤 - 包括 ***型別安全 (type-safety)***、***樹搖優化 (tree-shaking)*** 以及一致且 ***直觀的 API (intuitive API)***。通過專注於這些基礎並以 ***框架無關 (framework agnostic)*** 的方式提供,我們希望這些工具和模式能在您的應用程式中更普及。在應用程式開發中,適當的執行控制常常被忽視,導致可能預防的效能問題、競爭條件 (race conditions) 和使用者體驗不佳。TanStack Pacer 幫助您從一開始就正確實現這些關鍵模式! + +速率限制 (Rate Limiting)、節流 (Throttling) 和防抖 (Debouncing) 是三種控制函式執行頻率的截然不同的方法。每種技術以不同方式阻擋執行,使它們成為「有損耗的 (lossy)」- 這意味著當函式被要求過於頻繁執行時,某些呼叫將不會執行。了解何時使用每種方法對於構建高效能且可靠的應用程式至關重要。本指南將涵蓋 TanStack Pacer 的速率限制概念。 > [!NOTE] -> TanStack Pacer 目前僅是一個前端函式庫 (front-end library)。這些是用於客戶端速率限制 (client-side rate-limiting) 的實用工具。 +> TanStack Pacer 目前僅是一個前端函式庫。這些是用於客戶端速率限制的工具。 ## 速率限制概念 (Rate Limiting Concept) -速率限制是一種技術,用於限制函數在特定時間窗口內可以執行的速率。它特別適用於您希望防止函數被過於頻繁呼叫的場景,例如處理 API 請求或其他外部服務呼叫時。這是最*基礎* (naive) 的方法,因為它允許執行在達到配額前以突發方式發生。 +速率限制是一種技術,限制函式在特定時間窗口內可以執行的速率。它特別適用於您希望防止函式被過於頻繁呼叫的場景,例如處理 API 請求或其他外部服務呼叫時。這是最 *基礎 (naive)* 的方法,因為它允許執行在達到配額前以突發方式發生。 ### 速率限制視覺化 (Rate Limiting Visualization) ```text -Rate Limiting (limit: 3 calls per window) -Timeline: [1 second per tick] - Window 1 | Window 2 -Calls: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ -Executed: ✅ ✅ ✅ ❌ ❌ ✅ ✅ - [=== 3 allowed ===][=== blocked until window ends ===][=== new window =======] +速率限制 (限制: 每個窗口 3 次呼叫) +時間軸: [每秒一個刻度] + 窗口 1 | 窗口 2 +呼叫: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ +已執行: ✅ ✅ ✅ ❌ ❌ ✅ ✅ + [=== 允許 3 次 ===][=== 阻擋直到窗口結束 ===][=== 新窗口 =======] +``` + +### 窗口類型 (Window Types) + +TanStack Pacer 支援兩種速率限制窗口類型: + +1. **固定窗口 (Fixed Window)** (預設) + - 嚴格的窗口,在窗口期後重置 + - 窗口內的所有執行都計入限制 + - 窗口期後完全重置 + - 可能在窗口邊界處導致突發行為 + +2. **滑動窗口 (Sliding Window)** + - 滾動窗口,允許舊執行到期後新執行 + - 隨時間提供更一致的執行速率 + - 更適合維持穩定的執行流 + - 防止窗口邊界處的突發行為 + +以下是滑動窗口速率限制的視覺化: + +```text +滑動窗口速率限制 (限制: 每個窗口 3 次呼叫) +時間軸: [每秒一個刻度] + 窗口 1 | 窗口 2 +呼叫: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ +已執行: ✅ ✅ ✅ ❌ ✅ ✅ ✅ + [=== 允許 3 次 ===][=== 舊執行到期,新執行允許 ===][=== 繼續滑動 =======] ``` +關鍵差異在於,使用滑動窗口時,一旦最舊的執行到期,就允許新的執行。這創造了比固定窗口方法更一致的執行流。 + ### 何時使用速率限制 (When to Use Rate Limiting) 速率限制在處理可能意外壓垮後端服務或導致瀏覽器效能問題的前端操作時特別重要。 常見使用案例包括: -- 防止快速使用者互動 (如按鈕點擊或表單提交) 導致的意外 API 濫發 (API spam) +- 防止快速使用者互動(例如按鈕點擊或表單提交)導致的意外 API 濫發 - 可接受突發行為但希望限制最大速率的場景 - 防止意外無限迴圈或遞迴操作 -### 何時不應使用速率限制 (When Not to Use Rate Limiting) +### 何時不使用速率限制 (When Not to Use Rate Limiting) -速率限制是控制函數執行頻率最基礎的方法。它是這三種技術中最不靈活且限制最多的。考慮使用[節流](../guides/throttling)或[防抖](../guides/debouncing)來獲得更分散的執行。 +速率限制是控制函式執行頻率最基礎的方法。它是三種技術中最不靈活且限制最多的。考慮使用 [節流 (throttling)](../guides/throttling) 或 [防抖 (debouncing)](../guides/debouncing) 來實現更分散的執行。 > [!TIP] -> 在大多數使用案例中,您可能不希望使用「速率限制」。考慮改用[節流](../guides/throttling)或[防抖](../guides/debouncing)。 +> 對於大多數使用案例,您很可能不希望使用「速率限制」。考慮使用 [節流 (throttling)](../guides/throttling) 或 [防抖 (debouncing)](../guides/debouncing) 代替。 -速率限制的「損耗性」也意味著某些執行將被拒絕並丟失。如果您需要確保所有執行始終成功,這可能會成為問題。考慮使用[佇列](../guides/queueing),如果您需要確保所有執行都被排隊等待執行,但通過節流延遲來減慢執行速率。 +速率限制的「有損耗 (lossy)」特性也意味著某些執行將被拒絕並丟失。如果您需要確保所有執行始終成功,這可能會是個問題。考慮使用 [隊列 (queueing)](../guides/queueing) 如果您需要確保所有執行都被排隊等待執行,但通過節流延遲來減慢執行速率。 ## TanStack Pacer 中的速率限制 (Rate Limiting in TanStack Pacer) -TanStack Pacer 通過 `RateLimiter` 和 `AsyncRateLimiter` 類別 (及其對應的 `rateLimit` 和 `asyncRateLimit` 函數) 提供同步和非同步速率限制功能。 +TanStack Pacer 分別通過 `RateLimiter` 和 `AsyncRateLimiter` 類別(以及它們對應的 `rateLimit` 和 `asyncRateLimit` 函式)提供同步和非同步速率限制。 ### 使用 `rateLimit` 的基本用法 (Basic Usage with `rateLimit`) -`rateLimit` 函數是為任何函數添加速率限制的最簡單方法。它非常適合大多數只需要執行簡單限制的使用案例。 +`rateLimit` 函式是為任何函式添加速率限制的最簡單方法。它非常適合您只需要執行簡單限制的大多數使用案例。 ```ts import { rateLimit } from '@tanstack/pacer' @@ -61,8 +92,9 @@ const rateLimitedApi = rateLimit( { limit: 5, window: 60 * 1000, // 1 分鐘,以毫秒為單位 + windowType: 'fixed', // 預設 onReject: (rateLimiter) => { - console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`) + console.log(`超過速率限制。請在 ${rateLimiter.getMsUntilNextWindow()} 毫秒後重試`) } } ) @@ -73,12 +105,12 @@ rateLimitedApi('user-2') // ✅ 執行 rateLimitedApi('user-3') // ✅ 執行 rateLimitedApi('user-4') // ✅ 執行 rateLimitedApi('user-5') // ✅ 執行 -rateLimitedApi('user-6') // ❌ 拒絕,直到窗口重置 +rateLimitedApi('user-6') // ❌ 拒絕直到窗口重置 ``` ### 使用 `RateLimiter` 類別的高級用法 (Advanced Usage with `RateLimiter` Class) -對於需要對速率限制行為進行額外控制的更複雜場景,您可以直接使用 `RateLimiter` 類別。這使您能夠訪問其他方法和狀態資訊。 +對於需要額外控制速率限制行為的更複雜場景,您可以直接使用 `RateLimiter` 類別。這讓您可以訪問其他方法和狀態資訊。 ```ts import { RateLimiter } from '@tanstack/pacer' @@ -90,10 +122,10 @@ const limiter = new RateLimiter( limit: 5, window: 60 * 1000, onExecute: (rateLimiter) => { - console.log('Function executed', rateLimiter.getExecutionCount()) + console.log('函式已執行', rateLimiter.getExecutionCount()) }, onReject: (rateLimiter) => { - console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`) + console.log(`超過速率限制。請在 ${rateLimiter.getMsUntilNextWindow()} 毫秒後重試`) } } ) @@ -103,7 +135,7 @@ console.log(limiter.getRemainingInWindow()) // 當前窗口中剩餘的呼叫次 console.log(limiter.getExecutionCount()) // 成功執行的總次數 console.log(limiter.getRejectionCount()) // 被拒絕執行的總次數 -// 嘗試執行 (返回表示成功的布林值) +// 嘗試執行(返回表示成功的布林值) limiter.maybeExecute('user-1') // 動態更新選項 @@ -113,20 +145,23 @@ limiter.setOptions({ limit: 10 }) // 增加限制 limiter.reset() ``` -### 啟用/停用 (Enabling/Disabling) +### 啟用/禁用 (Enabling/Disabling) + +`RateLimiter` 類別通過 `enabled` 選項支援啟用/禁用。使用 `setOptions` 方法,您可以隨時啟用/禁用速率限制器: -`RateLimiter` 類別通過 `enabled` 選項支援啟用/停用功能。使用 `setOptions` 方法,您可以隨時啟用/停用速率限制器: +> [!NOTE] +> `enabled` 選項啟用/禁用實際的函式執行。禁用速率限制器並不會關閉速率限制,它只是完全阻止函式執行。 ```ts const limiter = new RateLimiter(fn, { limit: 5, window: 1000, - enabled: false // 預設停用 + enabled: false // 預設禁用 }) limiter.setOptions({ enabled: true }) // 隨時啟用 ``` -如果您使用的是框架適配器 (framework adapter),其中速率限制器選項是響應式的 (reactive),您可以將 `enabled` 選項設置為條件值以動態啟用/停用速率限制器。但是,如果您直接使用 `rateLimit` 函數或 `RateLimiter` 類別,則必須使用 `setOptions` 方法來更改 `enabled` 選項,因為傳遞的選項實際上會傳遞給 `RateLimiter` 類別的建構函數。 +如果您使用的是框架適配器,其中速率限制器選項是響應式的,您可以將 `enabled` 選項設置為條件值以動態啟用/禁用速率限制器。但是,如果您使用 `rateLimit` 函式或直接使用 `RateLimiter` 類別,則必須使用 `setOptions` 方法來更改 `enabled` 選項,因為傳遞的選項實際上會傳遞給 `RateLimiter` 類別的建構函式。 ### 回調選項 (Callback Options) @@ -142,20 +177,20 @@ const limiter = new RateLimiter(fn, { window: 1000, onExecute: (rateLimiter) => { // 每次成功執行後呼叫 - console.log('Function executed', rateLimiter.getExecutionCount()) + console.log('函式已執行', rateLimiter.getExecutionCount()) }, onReject: (rateLimiter) => { // 當執行被拒絕時呼叫 - console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`) + console.log(`超過速率限制。請在 ${rateLimiter.getMsUntilNextWindow()} 毫秒後重試`) } }) ``` -`onExecute` 回調在每次成功執行速率限制函數後呼叫,而 `onReject` 回調在因速率限制而拒絕執行時呼叫。這些回調對於追蹤執行、更新 UI 狀態或向使用者提供反饋非常有用。 +`onExecute` 回調在速率限制函式每次成功執行後呼叫,而 `onReject` 回調在執行因速率限制被拒絕時呼叫。這些回調對於追蹤執行、更新 UI 狀態或向使用者提供反饋非常有用。 #### 非同步速率限制器回調 (Asynchronous Rate Limiter Callbacks) -非同步 `AsyncRateLimiter` 支援用於錯誤處理的額外回調: +非同步 `AsyncRateLimiter` 支援額外的錯誤處理回調: ```ts const asyncLimiter = new AsyncRateLimiter(async (id) => { @@ -165,15 +200,15 @@ const asyncLimiter = new AsyncRateLimiter(async (id) => { window: 1000, onExecute: (rateLimiter) => { // 每次成功執行後呼叫 - console.log('Async function executed', rateLimiter.getExecutionCount()) + console.log('非同步函式已執行', rateLimiter.getExecutionCount()) }, onReject: (rateLimiter) => { // 當執行被拒絕時呼叫 - console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`) + console.log(`超過速率限制。請在 ${rateLimiter.getMsUntilNextWindow()} 毫秒後重試`) }, onError: (error) => { - // 如果非同步函數拋出錯誤時呼叫 - console.error('Async function failed:', error) + // 如果非同步函式拋出錯誤時呼叫 + console.error('非同步函式失敗:', error) } }) ``` @@ -182,34 +217,29 @@ const asyncLimiter = new AsyncRateLimiter(async (id) => { ### 非同步速率限制 (Asynchronous Rate Limiting) -非同步速率限制器提供了一種強大的方式來處理具有速率限制的非同步操作,與同步版本相比具有幾個關鍵優勢。雖然同步速率限制器非常適合 UI 事件和即時反饋,但非同步版本專門設計用於處理 API 呼叫、資料庫操作和其他非同步任務。 +非同步速率限制器提供了一種強大的方式來處理帶有速率限制的非同步操作,與同步版本相比具有幾個關鍵優勢。雖然同步速率限制器非常適合 UI 事件和即時反饋,但非同步版本專門設計用於處理 API 呼叫、資料庫操作和其他非同步任務。 #### 與同步速率限制的主要差異 (Key Differences from Synchronous Rate Limiting) -1. **返回值處理** -與同步速率限制器返回表示成功的布林值不同,非同步版本允許您捕獲並使用來自速率限制函數的返回值。這在您需要處理 API 呼叫或其他非同步操作的結果時特別有用。`maybeExecute` 方法返回一個 Promise,該 Promise 解析為函數的返回值,允許您等待結果並適當處理。 +1. **返回值處理 (Return Value Handling)** +與返回表示成功與否的布林值的同步速率限制器不同,非同步版本允許您捕獲並使用來自速率限制函式的返回值。這在您需要使用 API 呼叫或其他非同步操作的結果時特別有用。`maybeExecute` 方法返回一個 Promise,該 Promise 解析為函式的返回值,允許您等待結果並適當地處理它。 -2. **增強的回調系統** -非同步速率限制器提供比同步版本更複雜的回調系統。此系統包括: -- `onExecute`:每次成功執行後呼叫,提供速率限制器實例 -- `onReject`:當因速率限制而拒絕執行時呼叫,提供速率限制器實例 -- `onError`:如果非同步函數拋出錯誤時呼叫,提供錯誤和速率限制器實例 +2. **不同的回調 (Different Callbacks)** +`AsyncRateLimiter` 支援以下回調,而不僅僅是同步版本中的 `onExecute`: +- `onSuccess`:每次成功執行後呼叫,提供速率限制器實例 +- `onSettled`:每次執行後呼叫,提供速率限制器實例 +- `onError`:如果非同步函式拋出錯誤時呼叫,提供錯誤和速率限制器實例 -3. **執行追蹤** -非同步速率限制器通過以下幾種方法提供全面的執行追蹤: -- `getExecutionCount()`:成功執行的次數 -- `getRejectionCount()`:被拒絕執行的次數 -- `getRemainingInWindow()`:當前窗口中剩餘的執行次數 -- `getMsUntilNextWindow()`:距離下一個窗口開始的毫秒數 +非同步和同步速率限制器都支援 `onReject` 回調來處理被阻擋的執行。 -4. **順序執行** -非同步速率限制器確保後續執行等待前一次呼叫完成後才開始。這防止了執行順序錯亂,並保證每次呼叫處理最新的資料。這在處理依賴於先前呼叫結果的操作或維護資料一致性至關重要時特別重要。 +3. **順序執行 (Sequential Execution)** +由於速率限制器的 `maybeExecute` 方法返回一個 Promise,您可以選擇在開始下一個執行之前等待每個執行。這讓您可以控制執行順序並確保每個呼叫處理最新的數據。這在處理依賴於先前呼叫結果的操作或當維護數據一致性至關重要時特別有用。 -例如,如果您正在更新使用者的個人資料,然後立即獲取其更新後的資料,非同步速率限制器將確保獲取操作等待更新完成,防止可能獲取過時資料的競爭條件 (race conditions)。 +例如,如果您正在更新使用者的個人資料然後立即獲取其更新後的數據,您可以在開始獲取之前等待更新操作: #### 基本用法範例 (Basic Usage Example) -這是一個基本範例,展示如何將非同步速率限制器用於 API 操作: +以下是一個基本範例,展示如何使用非同步速率限制器進行 API 操作: ```ts const rateLimitedApi = asyncRateLimit( @@ -221,13 +251,13 @@ const rateLimitedApi = asyncRateLimit( limit: 5, window: 1000, onExecute: (limiter) => { - console.log('API call succeeded:', limiter.getExecutionCount()) + console.log('API 呼叫成功:', limiter.getExecutionCount()) }, onReject: (limiter) => { - console.log(`Rate limit exceeded. Try again in ${limiter.getMsUntilNextWindow()}ms`) + console.log(`超過速率限制。請在 ${limiter.getMsUntilNextWindow()} 毫秒後重試`) }, onError: (error, limiter) => { - console.error('API call failed:', error) + console.error('API 呼叫失敗:', error) } } ) @@ -236,22 +266,9 @@ const rateLimitedApi = asyncRateLimit( const result = await rateLimitedApi('123') ``` -#### 高級模式 (Advanced Patterns) - -非同步速率限制器可以與各種模式結合以解決複雜問題: - -1. **狀態管理整合** -當將非同步速率限制器與狀態管理系統 (如 React 的 useState 或 Solid 的 createSignal) 一起使用時,您可以創建強大的模式來處理載入狀態、錯誤狀態和資料更新。速率限制器的回調為根據操作的成功或失敗更新 UI 狀態提供了完美的鉤子。 - -2. **競爭條件預防** -速率限制模式自然防止了許多場景中的競爭條件。當應用程式的多個部分嘗試同時更新同一資源時,速率限制器確保更新在配置的限制內發生,同時仍向所有呼叫者提供結果。 - -3. **錯誤恢復** -非同步速率限制器的錯誤處理能力使其成為實現重試邏輯和錯誤恢復模式的理想選擇。您可以使用 `onError` 回調來實現自訂錯誤處理策略,例如指數退避 (exponential backoff) 或回退機制 (fallback mechanisms)。 - ### 框架適配器 (Framework Adapters) -每個框架適配器都提供建立在核心速率限制功能之上的鉤子 (hooks),以與框架的狀態管理系統集成。每個框架都提供如 `createRateLimiter`、`useRateLimitedCallback`、`useRateLimitedState` 或 `useRateLimitedValue` 等鉤子。 +每個框架適配器都提供建立在核心速率限制功能之上的鉤子,以與框架的狀態管理系統集成。每個框架都有可用的鉤子,如 `createRateLimiter`、`useRateLimitedCallback`、`useRateLimitedState` 或 `useRateLimitedValue`。 以下是一些範例: @@ -272,10 +289,10 @@ const handleFetch = useRateLimitedCallback( { limit: 5, window: 1000 } ) -// 基於狀態的鉤子,用於響應式狀態管理 +// 用於響應式狀態管理的基於狀態的鉤子 const [instantState, setInstantState] = useState('') const [rateLimitedValue] = useRateLimitedValue( - instantState, // 要進行速率限制的值 + instantState, // 要速率限制的值 { limit: 5, window: 1000 } ) ``` @@ -291,12 +308,12 @@ const limiter = createRateLimiter( { limit: 5, window: 1000 } ) -// 基於信號 (Signal) 的鉤子,用於狀態管理 +// 用於狀態管理的基於信號的鉤子 const [value, setValue, limiter] = createRateLimitedSignal('', { limit: 5, window: 1000, onExecute: (limiter) => { - console.log('Total executions:', limiter.getExecutionCount()) + console.log('總執行次數:', limiter.getExecutionCount()) } }) ``` diff --git a/docs/zh-hant/guides/throttling.md b/docs/zh-hant/guides/throttling.md index fe8b691fa..05966ca4a 100644 --- a/docs/zh-hant/guides/throttling.md +++ b/docs/zh-hant/guides/throttling.md @@ -1,61 +1,61 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:06:13.842Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:47:08.677Z' title: 節流指南 id: throttling --- 節流控制指南 (Throttling Guide) -速率限制 (Rate Limiting)、節流控制 (Throttling) 和防抖動 (Debouncing) 是三種控制函數執行頻率的技術。每種技術以不同方式阻擋執行,屬於「有損」機制 — 這意味當函數被頻繁呼叫時,部分呼叫將不會執行。了解何時使用每種技術對於構建高效可靠的應用程式至關重要。本指南將介紹 TanStack Pacer 的節流控制概念。 +速率限制 (Rate Limiting)、節流控制 (Throttling) 和防抖動 (Debouncing) 是三種控制函數執行頻率的不同方法。每種技術以不同方式阻擋執行,使它們成為「有損」的 - 這意味著當函數呼叫過於頻繁時,部分呼叫將不會執行。了解何時使用每種方法對於構建高效能且可靠的應用程式至關重要。本指南將介紹 TanStack Pacer 的節流控制概念。 ## 節流控制概念 -節流控制確保函數執行在時間上均勻分佈。與允許短時間內突發執行的速率限制不同,也不同於等待活動停止的防抖動技術,節流控制通過在呼叫之間強制保持一致的間隔來創建更平滑的執行模式。如果您設定每秒執行一次的節流,無論呼叫請求多麼頻繁,執行都會保持均勻間隔。 +節流控制確保函數執行在時間上均勻分佈。與允許突發執行直到達到限制的速率限制 (Rate Limiting) 不同,也不同於等待活動停止的防抖動 (Debouncing),節流控制通過在呼叫之間強制一致的延遲來創建更平滑的執行模式。如果您設定每秒執行一次的節流控制,無論請求多麼頻繁,呼叫都會均勻間隔。 ### 節流控制視覺化 ```text -節流控制 (每 3 個 tick 執行一次) -時間軸: [每秒一個 tick] -呼叫: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ -實際執行: ✅ ❌ ⏳ -> ✅ ❌ ❌ ❌ ✅ ✅ +節流控制 (每 3 個刻度執行一次) +時間軸: [每秒一個刻度] +呼叫: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ �️ ⬇️ +已執行: ✅ ❌ ⏳ -> ✅ ❌ ❌ ❌ ✅ ✅ [=================================================================] - ^ 每 3 個 tick 只允許執行一次, + ^ 每 3 個刻度只允許一次執行, 無論進行了多少次呼叫 - [首次突發] [更多呼叫] [間隔呼叫] - 首次執行後 等待週期結束後 每次等待週期 - 開始節流 執行 結束後執行 + [第一次突發] [更多呼叫] [間隔呼叫] + 第一次執行 等待週期後執行 每次等待週期 + 然後節流 通過後執行 ``` ### 何時使用節流控制 -當您需要一致且可預測的執行時機時,節流控制特別有效。這使其成為處理頻繁事件或更新的理想選擇,可實現平滑可控的行為。 +當您需要一致且可預測的執行時機時,節流控制特別有效。這使其成為處理頻繁事件或更新的理想選擇,您希望獲得平滑、受控的行為。 常見使用場景包括: -- 需要定時更新的 UI 元件(例如進度指示器) -- 不應讓瀏覽器過載的滾動或調整大小事件處理程序 -- 需要固定間隔的即時資料輪詢 +- 需要一致時機的 UI 更新(例如進度指示器) +- 不應壓垮瀏覽器的滾動或調整大小事件處理程序 +- 需要一致間隔的即時資料輪詢 - 需要穩定節奏的資源密集型操作 - 遊戲循環更新或動畫幀處理 - 使用者輸入時的即時搜尋建議 -### 何時不應使用節流控制 +### 何時不使用節流控制 -以下情況可能不適合使用節流控制: -- 您希望等待活動停止(改用 [防抖動](../guides/debouncing)) -- 不能承受任何執行遺漏(改用 [佇列處理](../guides/queueing)) +在以下情況下,節流控制可能不是最佳選擇: +- 您想等待活動停止(改用 [防抖動](../guides/debouncing)) +- 您不能錯過任何執行(改用 [排隊](../guides/queueing)) > [!TIP] -> 當您需要平滑一致的執行時機時,節流控制通常是最佳選擇。它比速率限制提供更可預測的執行模式,比防抖動提供更即時的回饋。 +> 當您需要平滑、一致的執行時機時,節流控制通常是最佳選擇。它提供比速率限制更可預測的執行模式,比防抖動更即時的回饋。 ## TanStack Pacer 中的節流控制 -TanStack Pacer 通過 `Throttler` 和 `AsyncThrottler` 類別(及其對應的 `throttle` 和 `asyncThrottle` 函數)提供同步和非同步節流控制功能。 +TanStack Pacer 分別通過 `Throttler` 和 `AsyncThrottler` 類(及其對應的 `throttle` 和 `asyncThrottle` 函數)提供同步和非同步節流控制。 ### 使用 `throttle` 的基本用法 -`throttle` 函數是為任何函數添加節流控制的最簡單方式: +`throttle` 函數是為任何函數添加節流控制的最簡單方法: ```ts import { throttle } from '@tanstack/pacer' @@ -68,15 +68,15 @@ const throttledUpdate = throttle( } ) -// 在快速循環中,只會每 200 毫秒執行一次 +// 在快速循環中,僅每 200 毫秒執行一次 for (let i = 0; i < 100; i++) { - throttledUpdate(i) // 多數呼叫會被節流 + throttledUpdate(i) // 許多呼叫被節流 } ``` -### 使用 `Throttler` 類別的高級用法 +### 使用 `Throttler` 類的高級用法 -要更精確控制節流行為,可以直接使用 `Throttler` 類別: +為了更精確控制節流行為,您可以直接使用 `Throttler` 類: ```ts import { Throttler } from '@tanstack/pacer' @@ -87,27 +87,27 @@ const updateThrottler = new Throttler( ) // 獲取執行狀態資訊 -console.log(updateThrottler.getExecutionCount()) // 成功執行次數 -console.log(updateThrottler.getLastExecutionTime()) // 最後執行時間戳 +console.log(updateThrottler.getExecutionCount()) // 成功執行的次數 +console.log(updateThrottler.getLastExecutionTime()) // 最後執行的時間戳 // 取消任何待處理的執行 updateThrottler.cancel() ``` -### 前緣與後緣執行 +### 前導和尾隨執行 -同步節流器支援前緣和後緣執行: +同步節流器支援前導和尾隨邊緣執行: ```ts const throttledFn = throttle(fn, { wait: 200, - leading: true, // 首次呼叫立即執行 (預設) - trailing: true, // 等待週期後執行 (預設) + leading: true, // 第一次呼叫時執行(預設) + trailing: true, // 等待週期後執行(預設) }) ``` -- `leading: true` (預設) - 首次呼叫立即執行 -- `leading: false` - 跳過首次呼叫,等待後緣執行 +- `leading: true` (預設) - 第一次呼叫時立即執行 +- `leading: false` - 跳過第一次呼叫,等待尾隨執行 - `trailing: true` (預設) - 等待週期後執行最後一次呼叫 - `trailing: false` - 如果在等待週期內則跳過最後一次呼叫 @@ -116,24 +116,24 @@ const throttledFn = throttle(fn, { - `{ leading: false, trailing: true }` - 延遲所有執行 - `{ leading: true, trailing: false }` - 跳過排隊的執行 -### 啟用/停用功能 +### 啟用/停用 -`Throttler` 類別通過 `enabled` 選項支援啟用/停用功能。使用 `setOptions` 方法可以隨時啟用或停用節流器: +`Throttler` 類通過 `enabled` 選項支援啟用/停用。使用 `setOptions` 方法,您可以隨時啟用/停用節流器: ```ts const throttler = new Throttler(fn, { wait: 200, enabled: false }) // 預設停用 throttler.setOptions({ enabled: true }) // 隨時啟用 ``` -如果您使用的框架適配器支援響應式節流器選項,可以將 `enabled` 選項設為條件值以動態啟用/停用節流器。但是,如果直接使用 `throttle` 函數或 `Throttler` 類別,則必須使用 `setOptions` 方法更改 `enabled` 選項,因為傳遞的選項實際上是傳遞給 `Throttler` 類別的建構函數。 +如果您使用的是節流器選項具有反應性的框架適配器,您可以將 `enabled` 選項設定為條件值以動態啟用/停用節流器。但是,如果您直接使用 `throttle` 函數或 `Throttler` 類,則必須使用 `setOptions` 方法來更改 `enabled` 選項,因為傳遞的選項實際上會傳遞給 `Throttler` 類的構造函數。 -### 回呼選項 +### 回調選項 -同步和非同步節流器都支援回呼選項來處理節流生命週期的不同方面: +同步和非同步節流器都支援回調選項,以處理節流生命週期的不同方面: -#### 同步節流器回呼 +#### 同步節流器回調 -同步 `Throttler` 支援以下回呼: +同步 `Throttler` 支援以下回調: ```ts const throttler = new Throttler(fn, { @@ -145,11 +145,11 @@ const throttler = new Throttler(fn, { }) ``` -`onExecute` 回呼在每次成功執行節流函數後呼叫,可用於追蹤執行次數、更新 UI 狀態或執行清理操作。 +`onExecute` 回調在節流函數每次成功執行後呼叫,這對於追蹤執行、更新 UI 狀態或執行清理操作非常有用。 -#### 非同步節流器回呼 +#### 非同步節流器回調 -非同步 `AsyncThrottler` 支援額外的錯誤處理回呼: +非同步 `AsyncThrottler` 支援額外的錯誤處理回調: ```ts const asyncThrottler = new AsyncThrottler(async (value) => { @@ -161,43 +161,39 @@ const asyncThrottler = new AsyncThrottler(async (value) => { console.log('非同步函數已執行', throttler.getExecutionCount()) }, onError: (error) => { - // 非同步函數拋出錯誤時呼叫 - console.error('非同步函數執行失敗:', error) + // 如果非同步函數拋出錯誤則呼叫 + console.error('非同步函數失敗:', error) } }) ``` -`onExecute` 回呼的工作方式與同步節流器相同,而 `onError` 回呼允許您優雅地處理錯誤而不中斷節流鏈。這些回呼特別適用於追蹤執行次數、更新 UI 狀態、處理錯誤、執行清理操作和記錄執行指標。 +`onExecute` 回調的工作方式與同步節流器相同,而 `onError` 回調允許您優雅地處理錯誤而不中斷節流鏈。這些回調對於追蹤執行計數、更新 UI 狀態、處理錯誤、執行清理操作和記錄執行指標特別有用。 ### 非同步節流控制 -非同步節流器提供了一種強大的方式來處理非同步操作的節流控制,相比同步版本具有幾個關鍵優勢。雖然同步節流器適用於 UI 事件和即時回饋,但非同步版本專為處理 API 呼叫、資料庫操作和其他非同步任務而設計。 +非同步節流器提供了一種強大的方式來處理具有節流控制的非同步操作,與同步版本相比具有幾個關鍵優勢。雖然同步節流器非常適合 UI 事件和即時回饋,但非同步版本專門設計用於處理 API 呼叫、數據庫操作和其他非同步任務。 -#### 與同步節流的主要區別 +#### 與同步節流控制的主要區別 1. **返回值處理** -與返回 void 的同步節流器不同,非同步版本允許您捕獲和使用節流函數的返回值。這在需要處理 API 呼叫結果或其他非同步操作時特別有用。`maybeExecute` 方法返回一個 Promise,該 Promise 解析為函數的返回值,允許您等待結果並適當處理。 +與返回 void 的同步節流器不同,非同步版本允許您捕獲和使用節流函數的返回值。這在您需要使用 API 呼叫或其他非同步操作的結果時特別有用。`maybeExecute` 方法返回一個 Promise,該 Promise 解析為函數的返回值,允許您等待結果並適當處理。 -2. **增強的回呼系統** -非同步節流器提供比同步版本的單一 `onExecute` 回呼更複雜的回呼系統。該系統包括: -- `onSuccess`: 非同步函數成功完成時呼叫,提供結果和節流器實例 -- `onError`: 非同步函數拋出錯誤時呼叫,提供錯誤和節流器實例 -- `onSettled`: 每次執行嘗試後呼叫,無論成功與否 +2. **不同的回調** +`AsyncThrottler` 支援以下回調,而不僅僅是同步版本中的 `onExecute`: +- `onSuccess`:每次成功執行後呼叫,提供節流器實例 +- `onSettled`:每次執行後呼叫,提供節流器實例 +- `onError`:如果非同步函數拋出錯誤則呼叫,提供錯誤和節流器實例 -3. **執行追蹤** -非同步節流器通過多種方法提供全面的執行追蹤: -- `getSuccessCount()`: 成功執行次數 -- `getErrorCount()`: 失敗執行次數 -- `getSettledCount()`: 已完成的執行總數 (成功 + 失敗) +非同步和同步節流器都支援 `onExecute` 回調以處理成功執行。 -4. **順序執行** -非同步節流器確保後續執行等待前一次呼叫完成後才開始。這可防止執行順序錯亂,並保證每次呼叫處理的都是最新資料。這在處理依賴前次呼叫結果的操作或維護資料一致性至關重要時特別重要。 +3. **順序執行** +由於節流器的 `maybeExecute` 方法返回一個 Promise,您可以選擇在開始下一個執行之前等待每個執行。這使您可以控制執行順序,並確保每個呼叫處理最新的數據。這在處理依賴於先前呼叫結果的操作或維護數據一致性至關重要時特別有用。 -例如,如果您正在更新使用者個人資料並立即獲取其更新後的資料,非同步節流器將確保獲取操作等待更新完成,防止可能獲取過時資料的競爭條件。 +例如,如果您正在更新用戶的個人資料,然後立即獲取其更新的數據,您可以在開始獲取之前等待更新操作: -#### 基本用法範例 +#### 基本用法示例 -以下是展示如何使用非同步節流器進行搜尋操作的基本範例: +以下是一個基本示例,展示如何使用非同步節流器進行搜尋操作: ```ts const throttledSearch = asyncThrottle( @@ -220,24 +216,11 @@ const throttledSearch = asyncThrottle( const results = await throttledSearch('query') ``` -#### 高級模式 - -非同步節流器可以與各種模式結合以解決複雜問題: - -1. **狀態管理整合** -當將非同步節流器與狀態管理系統(如 React 的 useState 或 Solid 的 createSignal)結合使用時,可以創建強大的模式來處理載入狀態、錯誤狀態和資料更新。節流器的回呼提供了根據操作成功或失敗更新 UI 狀態的完美鉤子。 - -2. **競爭條件預防** -節流模式自然預防了許多場景中的競爭條件。當應用程式的多個部分嘗試同時更新同一資源時,節流器確保更新以受控速率進行,同時仍向所有呼叫者提供結果。 - -3. **錯誤恢復** -非同步節流器的錯誤處理能力使其成為實現重試邏輯和錯誤恢復模式的理想選擇。您可以使用 `onError` 回呼實現自定義錯誤處理策略,例如指數退避或回退機制。 - ### 框架適配器 -每個框架適配器都提供建立在核心節流功能之上的鉤子,以與框架的狀態管理系統整合。每個框架都提供如 `createThrottler`、`useThrottledCallback`、`useThrottledState` 或 `useThrottledValue` 等鉤子。 +每個框架適配器都提供建立在核心節流功能之上的鉤子,以與框架的狀態管理系統集成。每個框架都有可用的鉤子,如 `createThrottler`、`useThrottledCallback`、`useThrottledState` 或 `useThrottledValue`。 -以下是一些範例: +以下是一些示例: #### React @@ -250,13 +233,13 @@ const throttler = useThrottler( { wait: 200 } ) -// 用於基本用例的簡單回呼鉤子 +// 用於基本用例的簡單回調鉤子 const handleUpdate = useThrottledCallback( (value: number) => updateProgressBar(value), { wait: 200 } ) -// 用於響應式狀態管理的基於狀態的鉤子 +// 用於反應式狀態管理的基於狀態的鉤子 const [instantState, setInstantState] = useState(0) const [throttledValue] = useThrottledValue( instantState, // 要節流的值 @@ -284,4 +267,4 @@ const [value, setValue, throttler] = createThrottledSignal(0, { }) ``` -每個框架適配器都提供與框架狀態管理系統整合的鉤子,同時保持核心節流功能。 +每個框架適配器都提供與框架狀態管理系統集成的鉤子,同時保持核心節流功能。 diff --git a/docs/zh-hant/reference/classes/asyncdebouncer.md b/docs/zh-hant/reference/classes/asyncdebouncer.md index c00411a1b..b57c82ef1 100644 --- a/docs/zh-hant/reference/classes/asyncdebouncer.md +++ b/docs/zh-hant/reference/classes/asyncdebouncer.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:04:17.689Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:45:08.665Z' id: AsyncDebouncer title: AsyncDebouncer --- @@ -9,7 +9,7 @@ title: AsyncDebouncer # Class: AsyncDebouncer\ -Defined in: [async-debouncer.ts:73](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L73) +Defined in: [async-debouncer.ts:77](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L77) A class that creates an async debounced function. @@ -20,17 +20,21 @@ or input changes where you only want to execute the handler after the events hav Unlike throttling which allows execution at regular intervals, debouncing prevents any execution until the function stops being called for the specified delay period. +Unlike the non-async Debouncer, this async version supports returning values from the debounced function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the debounced function. + ## Example ```ts const asyncDebouncer = new AsyncDebouncer(async (value: string) => { - await searchAPI(value); + const results = await searchAPI(value); + return results; // Return value is preserved }, { wait: 500 }); // Called on each keystroke but only executes after 500ms of no typing -inputElement.addEventListener('input', () => { - asyncDebouncer.maybeExecute(inputElement.value); -}); +// Returns the API response directly +const results = await asyncDebouncer.maybeExecute(inputElement.value); ``` ## Type Parameters @@ -45,7 +49,7 @@ inputElement.addEventListener('input', () => { new AsyncDebouncer(fn, initialOptions): AsyncDebouncer ``` -Defined in: [async-debouncer.ts:86](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L86) +Defined in: [async-debouncer.ts:90](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L90) #### Parameters @@ -69,7 +73,7 @@ Defined in: [async-debouncer.ts:86](https://github.com/TanStack/pacer/blob/main/ cancel(): void ``` -Defined in: [async-debouncer.ts:195](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L195) +Defined in: [async-debouncer.ts:199](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L199) Cancels any pending execution or aborts any execution in progress @@ -85,7 +89,7 @@ Cancels any pending execution or aborts any execution in progress getErrorCount(): number ``` -Defined in: [async-debouncer.ts:224](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L224) +Defined in: [async-debouncer.ts:228](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L228) Returns the number of times the function has errored @@ -101,7 +105,7 @@ Returns the number of times the function has errored getIsExecuting(): boolean ``` -Defined in: [async-debouncer.ts:238](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L238) +Defined in: [async-debouncer.ts:242](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L242) Returns `true` if there is currently an execution in progress @@ -117,7 +121,7 @@ Returns `true` if there is currently an execution in progress getIsPending(): boolean ``` -Defined in: [async-debouncer.ts:231](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L231) +Defined in: [async-debouncer.ts:235](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L235) Returns `true` if there is a pending execution queued up for trailing execution @@ -133,7 +137,7 @@ Returns `true` if there is a pending execution queued up for trailing execution getLastResult(): undefined | ReturnType ``` -Defined in: [async-debouncer.ts:203](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L203) +Defined in: [async-debouncer.ts:207](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L207) Returns the last result of the debounced function @@ -149,7 +153,7 @@ Returns the last result of the debounced function getOptions(): Required> ``` -Defined in: [async-debouncer.ts:112](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L112) +Defined in: [async-debouncer.ts:116](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L116) Returns the current debouncer options @@ -165,7 +169,7 @@ Returns the current debouncer options getSettleCount(): number ``` -Defined in: [async-debouncer.ts:217](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L217) +Defined in: [async-debouncer.ts:221](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L221) Returns the number of times the function has settled (completed or errored) @@ -181,7 +185,7 @@ Returns the number of times the function has settled (completed or errored) getSuccessCount(): number ``` -Defined in: [async-debouncer.ts:210](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L210) +Defined in: [async-debouncer.ts:214](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L214) Returns the number of times the function has been executed successfully @@ -197,7 +201,7 @@ Returns the number of times the function has been executed successfully maybeExecute(...args): Promise> ``` -Defined in: [async-debouncer.ts:120](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L120) +Defined in: [async-debouncer.ts:124](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L124) Attempts to execute the debounced function If a call is already in progress, it will be queued @@ -220,7 +224,7 @@ If a call is already in progress, it will be queued setOptions(newOptions): void ``` -Defined in: [async-debouncer.ts:100](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L100) +Defined in: [async-debouncer.ts:104](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L104) Updates the debouncer options Returns the new options state diff --git a/docs/zh-hant/reference/classes/asyncratelimiter.md b/docs/zh-hant/reference/classes/asyncratelimiter.md index 6109963cc..776fa08fb 100644 --- a/docs/zh-hant/reference/classes/asyncratelimiter.md +++ b/docs/zh-hant/reference/classes/asyncratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:04:17.680Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:45:08.656Z' id: AsyncRateLimiter title: AsyncRateLimiter --- @@ -9,7 +9,7 @@ title: AsyncRateLimiter # Class: AsyncRateLimiter\ -Defined in: [async-rate-limiter.ts:76](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L76) +Defined in: [async-rate-limiter.ts:95](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L95) A class that creates an async rate-limited function. @@ -17,6 +17,16 @@ Rate limiting is a simple approach that allows a function to execute up to a lim then blocks all subsequent calls until the window passes. This can lead to "bursty" behavior where all executions happen immediately, followed by a complete block. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + +Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + For smoother execution patterns, consider using: - Throttling: Ensures consistent spacing between executions (e.g. max once per 200ms) - Debouncing: Waits for a pause in calls before executing (e.g. after 500ms of no calls) @@ -29,11 +39,12 @@ smoothing out frequent events, throttling or debouncing usually provide better u ```ts const rateLimiter = new AsyncRateLimiter( async (id: string) => await api.getData(id), - { limit: 5, window: 1000 } // 5 calls per second + { limit: 5, window: 1000, windowType: 'sliding' } // 5 calls per second with sliding window ); // Will execute immediately until limit reached, then block -await rateLimiter.maybeExecute('123'); +// Returns the API response directly +const data = await rateLimiter.maybeExecute('123'); ``` ## Type Parameters @@ -48,7 +59,7 @@ await rateLimiter.maybeExecute('123'); new AsyncRateLimiter(fn, initialOptions): AsyncRateLimiter ``` -Defined in: [async-rate-limiter.ts:85](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L85) +Defined in: [async-rate-limiter.ts:105](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L105) #### Parameters @@ -72,7 +83,7 @@ Defined in: [async-rate-limiter.ts:85](https://github.com/TanStack/pacer/blob/ma getErrorCount(): number ``` -Defined in: [async-rate-limiter.ts:209](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L209) +Defined in: [async-rate-limiter.ts:250](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L250) Returns the number of times the function has errored @@ -82,15 +93,33 @@ Returns the number of times the function has errored *** +### getIsExecuting() + +```ts +getIsExecuting(): boolean +``` + +Defined in: [async-rate-limiter.ts:264](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L264) + +Returns whether the function is currently executing + +#### Returns + +`boolean` + +*** + ### getMsUntilNextWindow() ```ts getMsUntilNextWindow(): number ``` -Defined in: [async-rate-limiter.ts:188](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L188) +Defined in: [async-rate-limiter.ts:225](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L225) Returns the number of milliseconds until the next execution will be possible +For fixed windows, this is the time until the current window resets +For sliding windows, this is the time until the oldest execution expires #### Returns @@ -104,7 +133,7 @@ Returns the number of milliseconds until the next execution will be possible getOptions(): Required> ``` -Defined in: [async-rate-limiter.ts:106](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L106) +Defined in: [async-rate-limiter.ts:126](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L126) Returns the current rate limiter options @@ -120,7 +149,7 @@ Returns the current rate limiter options getRejectionCount(): number ``` -Defined in: [async-rate-limiter.ts:216](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L216) +Defined in: [async-rate-limiter.ts:257](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L257) Returns the number of times the function has been rejected @@ -136,7 +165,7 @@ Returns the number of times the function has been rejected getRemainingInWindow(): number ``` -Defined in: [async-rate-limiter.ts:180](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L180) +Defined in: [async-rate-limiter.ts:215](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L215) Returns the number of remaining executions allowed in the current window @@ -152,7 +181,7 @@ Returns the number of remaining executions allowed in the current window getSettleCount(): number ``` -Defined in: [async-rate-limiter.ts:202](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L202) +Defined in: [async-rate-limiter.ts:243](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L243) Returns the number of times the function has been settled @@ -168,7 +197,7 @@ Returns the number of times the function has been settled getSuccessCount(): number ``` -Defined in: [async-rate-limiter.ts:195](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L195) +Defined in: [async-rate-limiter.ts:236](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L236) Returns the number of times the function has been executed @@ -184,7 +213,7 @@ Returns the number of times the function has been executed maybeExecute(...args): Promise> ``` -Defined in: [async-rate-limiter.ts:126](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L126) +Defined in: [async-rate-limiter.ts:146](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L146) Attempts to execute the rate-limited function if within the configured limits. Will reject execution if the number of calls in the current window exceeds the limit. @@ -220,7 +249,7 @@ await rateLimiter.maybeExecute('arg1', 'arg2'); // Rejected reset(): void ``` -Defined in: [async-rate-limiter.ts:223](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L223) +Defined in: [async-rate-limiter.ts:271](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L271) Resets the rate limiter state @@ -236,7 +265,7 @@ Resets the rate limiter state setOptions(newOptions): void ``` -Defined in: [async-rate-limiter.ts:99](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L99) +Defined in: [async-rate-limiter.ts:119](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L119) Updates the rate limiter options Returns the new options state diff --git a/docs/zh-hant/reference/classes/asyncthrottler.md b/docs/zh-hant/reference/classes/asyncthrottler.md index b4d3e582f..f3e0ad110 100644 --- a/docs/zh-hant/reference/classes/asyncthrottler.md +++ b/docs/zh-hant/reference/classes/asyncthrottler.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:04:17.677Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:45:08.652Z' id: AsyncThrottler title: AsyncThrottler --- @@ -9,7 +9,7 @@ title: AsyncThrottler # Class: AsyncThrottler\ -Defined in: [async-throttler.ts:76](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L76) +Defined in: [async-throttler.ts:80](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L80) A class that creates an async throttled function. @@ -17,6 +17,10 @@ Throttling limits how often a function can be executed, allowing only one execut Unlike debouncing which resets the delay timer on each call, throttling ensures the function executes at a regular interval regardless of how often it's called. +Unlike the non-async Throttler, this async version supports returning values from the throttled function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the throttled function. + This is useful for rate-limiting API calls, handling scroll/resize events, or any scenario where you want to ensure a maximum execution frequency. @@ -24,13 +28,13 @@ ensure a maximum execution frequency. ```ts const throttler = new AsyncThrottler(async (value: string) => { - await saveToAPI(value); + const result = await saveToAPI(value); + return result; // Return value is preserved }, { wait: 1000 }); // Will only execute once per second no matter how often called -inputElement.addEventListener('input', () => { - throttler.maybeExecute(inputElement.value); -}); +// Returns the API response directly +const result = await throttler.maybeExecute(inputElement.value); ``` ## Type Parameters @@ -45,7 +49,7 @@ inputElement.addEventListener('input', () => { new AsyncThrottler(fn, initialOptions): AsyncThrottler ``` -Defined in: [async-throttler.ts:89](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L89) +Defined in: [async-throttler.ts:93](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L93) #### Parameters @@ -69,7 +73,7 @@ Defined in: [async-throttler.ts:89](https://github.com/TanStack/pacer/blob/main/ cancel(): void ``` -Defined in: [async-throttler.ts:187](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L187) +Defined in: [async-throttler.ts:191](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L191) Cancels any pending execution or aborts any execution in progress @@ -85,7 +89,7 @@ Cancels any pending execution or aborts any execution in progress getErrorCount(): number ``` -Defined in: [async-throttler.ts:237](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L237) +Defined in: [async-throttler.ts:241](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L241) Returns the number of times the function has errored @@ -101,7 +105,7 @@ Returns the number of times the function has errored getIsExecuting(): boolean ``` -Defined in: [async-throttler.ts:251](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L251) +Defined in: [async-throttler.ts:255](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L255) Returns the current executing state @@ -117,7 +121,7 @@ Returns the current executing state getIsPending(): boolean ``` -Defined in: [async-throttler.ts:244](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L244) +Defined in: [async-throttler.ts:248](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L248) Returns the current pending state @@ -133,7 +137,7 @@ Returns the current pending state getLastExecutionTime(): number ``` -Defined in: [async-throttler.ts:202](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L202) +Defined in: [async-throttler.ts:206](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L206) Returns the last execution time @@ -149,7 +153,7 @@ Returns the last execution time getLastResult(): undefined | ReturnType ``` -Defined in: [async-throttler.ts:216](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L216) +Defined in: [async-throttler.ts:220](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L220) Returns the last result of the debounced function @@ -165,7 +169,7 @@ Returns the last result of the debounced function getNextExecutionTime(): number ``` -Defined in: [async-throttler.ts:209](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L209) +Defined in: [async-throttler.ts:213](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L213) Returns the next execution time @@ -181,7 +185,7 @@ Returns the next execution time getOptions(): Required> ``` -Defined in: [async-throttler.ts:115](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L115) +Defined in: [async-throttler.ts:119](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L119) Returns the current options @@ -197,7 +201,7 @@ Returns the current options getSettleCount(): number ``` -Defined in: [async-throttler.ts:230](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L230) +Defined in: [async-throttler.ts:234](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L234) Returns the number of times the function has settled (completed or errored) @@ -213,7 +217,7 @@ Returns the number of times the function has settled (completed or errored) getSuccessCount(): number ``` -Defined in: [async-throttler.ts:223](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L223) +Defined in: [async-throttler.ts:227](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L227) Returns the number of times the function has been executed successfully @@ -229,7 +233,7 @@ Returns the number of times the function has been executed successfully maybeExecute(...args): Promise> ``` -Defined in: [async-throttler.ts:123](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L123) +Defined in: [async-throttler.ts:127](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L127) Attempts to execute the throttled function If a call is already in progress, it may be blocked or queued depending on the `wait` option @@ -252,7 +256,7 @@ If a call is already in progress, it may be blocked or queued depending on the ` setOptions(newOptions): void ``` -Defined in: [async-throttler.ts:103](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L103) +Defined in: [async-throttler.ts:107](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L107) Updates the throttler options Returns the new options state diff --git a/docs/zh-hant/reference/classes/ratelimiter.md b/docs/zh-hant/reference/classes/ratelimiter.md index efd59e2c0..61dce91b1 100644 --- a/docs/zh-hant/reference/classes/ratelimiter.md +++ b/docs/zh-hant/reference/classes/ratelimiter.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:04:17.664Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:45:08.639Z' id: RateLimiter title: RateLimiter --- @@ -9,7 +9,7 @@ title: RateLimiter # Class: RateLimiter\ -Defined in: [rate-limiter.ts:63](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L63) +Defined in: [rate-limiter.ts:77](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L77) A class that creates a rate-limited function. @@ -17,6 +17,12 @@ Rate limiting is a simple approach that allows a function to execute up to a lim then blocks all subsequent calls until the window passes. This can lead to "bursty" behavior where all executions happen immediately, followed by a complete block. +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + For smoother execution patterns, consider using: - Throttling: Ensures consistent spacing between executions (e.g. max once per 200ms) - Debouncing: Waits for a pause in calls before executing (e.g. after 500ms of no calls) @@ -29,7 +35,7 @@ smoothing out frequent events, throttling or debouncing usually provide better u ```ts const rateLimiter = new RateLimiter( (id: string) => api.getData(id), - { limit: 5, window: 1000 } // 5 calls per second + { limit: 5, window: 1000, windowType: 'sliding' } // 5 calls per second with sliding window ); // Will execute immediately until limit reached, then block @@ -48,7 +54,7 @@ rateLimiter.maybeExecute('123'); new RateLimiter(fn, initialOptions): RateLimiter ``` -Defined in: [rate-limiter.ts:69](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L69) +Defined in: [rate-limiter.ts:83](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L83) #### Parameters @@ -72,7 +78,7 @@ Defined in: [rate-limiter.ts:69](https://github.com/TanStack/pacer/blob/main/pac getExecutionCount(): number ``` -Defined in: [rate-limiter.ts:149](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L149) +Defined in: [rate-limiter.ts:175](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L175) Returns the number of times the function has been executed @@ -88,7 +94,7 @@ Returns the number of times the function has been executed getMsUntilNextWindow(): number ``` -Defined in: [rate-limiter.ts:171](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L171) +Defined in: [rate-limiter.ts:197](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L197) Returns the number of milliseconds until the next execution will be possible @@ -104,7 +110,7 @@ Returns the number of milliseconds until the next execution will be possible getOptions(): Required> ``` -Defined in: [rate-limiter.ts:90](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L90) +Defined in: [rate-limiter.ts:104](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L104) Returns the current rate limiter options @@ -120,7 +126,7 @@ Returns the current rate limiter options getRejectionCount(): number ``` -Defined in: [rate-limiter.ts:156](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L156) +Defined in: [rate-limiter.ts:182](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L182) Returns the number of times the function has been rejected @@ -136,7 +142,7 @@ Returns the number of times the function has been rejected getRemainingInWindow(): number ``` -Defined in: [rate-limiter.ts:163](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L163) +Defined in: [rate-limiter.ts:189](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L189) Returns the number of remaining executions allowed in the current window @@ -152,7 +158,7 @@ Returns the number of remaining executions allowed in the current window maybeExecute(...args): boolean ``` -Defined in: [rate-limiter.ts:109](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L109) +Defined in: [rate-limiter.ts:123](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L123) Attempts to execute the rate-limited function if within the configured limits. Will reject execution if the number of calls in the current window exceeds the limit. @@ -187,7 +193,7 @@ rateLimiter.maybeExecute('arg1', 'arg2'); // false reset(): void ``` -Defined in: [rate-limiter.ts:179](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L179) +Defined in: [rate-limiter.ts:208](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L208) Resets the rate limiter state @@ -203,7 +209,7 @@ Resets the rate limiter state setOptions(newOptions): void ``` -Defined in: [rate-limiter.ts:83](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L83) +Defined in: [rate-limiter.ts:97](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L97) Updates the rate limiter options Returns the new options state diff --git a/docs/zh-hant/reference/functions/asyncdebounce.md b/docs/zh-hant/reference/functions/asyncdebounce.md index b4c88db88..2e35dc5b5 100644 --- a/docs/zh-hant/reference/functions/asyncdebounce.md +++ b/docs/zh-hant/reference/functions/asyncdebounce.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-04-24T02:14:56.000Z' -translation-updated-at: '2025-05-06T20:27:49.589Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:45:08.636Z' id: asyncDebounce title: asyncDebounce --- @@ -10,21 +10,23 @@ title: asyncDebounce # Function: asyncDebounce() ```ts -function asyncDebounce(fn, initialOptions): (...args) => Promise +function asyncDebounce(fn, initialOptions): (...args) => Promise> ``` -Defined in: [async-debouncer.ts:219](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L219) +Defined in: [async-debouncer.ts:268](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-debouncer.ts#L268) Creates an async debounced function that delays execution until after a specified wait time. The debounced function will only execute once the wait period has elapsed without any new calls. If called again during the wait period, the timer resets and a new wait period begins. +Unlike the non-async Debouncer, this async version supports returning values from the debounced function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the debounced function. + ## Type Parameters • **TFn** *extends* [`AnyAsyncFunction`](../type-aliases/anyasyncfunction.md) -• **TArgs** *extends* `any`[] - ## Parameters ### fn @@ -33,7 +35,7 @@ If called again during the wait period, the timer resets and a new wait period b ### initialOptions -`Omit`\<[`AsyncDebouncerOptions`](../interfaces/asyncdebounceroptions.md)\<`TFn`, `TArgs`\>, `"enabled"`\> +`Omit`\<[`AsyncDebouncerOptions`](../interfaces/asyncdebounceroptions.md)\<`TFn`\>, `"enabled"`\> ## Returns @@ -46,21 +48,21 @@ If a call is already in progress, it will be queued #### args -...`TArgs` +...`Parameters`\<`TFn`\> ### Returns -`Promise`\<`void`\> +`Promise`\<`undefined` \| `ReturnType`\<`TFn`\>\> ## Example ```ts const debounced = asyncDebounce(async (value: string) => { - await saveToAPI(value); + const result = await saveToAPI(value); + return result; // Return value is preserved }, { wait: 1000 }); // Will only execute once, 1 second after the last call -await debounced("first"); // Cancelled -await debounced("second"); // Cancelled -await debounced("third"); // Executes after 1s +// Returns the API response directly +const result = await debounced("third"); ``` diff --git a/docs/zh-hant/reference/functions/asyncratelimit.md b/docs/zh-hant/reference/functions/asyncratelimit.md index 0a42f97af..d2ae794f7 100644 --- a/docs/zh-hant/reference/functions/asyncratelimit.md +++ b/docs/zh-hant/reference/functions/asyncratelimit.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:04:17.655Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:45:08.628Z' id: asyncRateLimit title: asyncRateLimit --- @@ -13,10 +13,20 @@ title: asyncRateLimit function asyncRateLimit(fn, initialOptions): (...args) => Promise> ``` -Defined in: [async-rate-limiter.ts:262](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L262) +Defined in: [async-rate-limiter.ts:322](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L322) Creates an async rate-limited function that will execute the provided function up to a maximum number of times within a time window. +Unlike the non-async rate limiter, this async version supports returning values from the rate-limited function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the rate-limited function. + +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + Note that rate limiting is a simpler form of execution control compared to throttling or debouncing: - A rate limiter will allow all executions until the limit is reached, then block all subsequent calls until the window resets - A throttler ensures even spacing between executions, which can be better for consistent performance @@ -72,10 +82,11 @@ await rateLimiter.maybeExecute('arg1', 'arg2'); // Rejected ## Example ```ts -// Rate limit to 5 calls per minute +// Rate limit to 5 calls per minute with a sliding window const rateLimited = asyncRateLimit(makeApiCall, { limit: 5, window: 60000, + windowType: 'sliding', onReject: (rateLimiter) => { console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } @@ -83,7 +94,8 @@ const rateLimited = asyncRateLimit(makeApiCall, { // First 5 calls will execute immediately // Additional calls will be rejected until the minute window resets -await rateLimited(); +// Returns the API response directly +const result = await rateLimited(); // For more even execution, consider using throttle instead: const throttled = throttle(makeApiCall, { wait: 12000 }); // One call every 12 seconds diff --git a/docs/zh-hant/reference/functions/asyncthrottle.md b/docs/zh-hant/reference/functions/asyncthrottle.md index 1f7b59d7a..1ca14a2ff 100644 --- a/docs/zh-hant/reference/functions/asyncthrottle.md +++ b/docs/zh-hant/reference/functions/asyncthrottle.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-04-24T02:14:56.000Z' -translation-updated-at: '2025-05-06T20:27:49.580Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:45:08.624Z' id: asyncThrottle title: asyncThrottle --- @@ -10,21 +10,23 @@ title: asyncThrottle # Function: asyncThrottle() ```ts -function asyncThrottle(fn, initialOptions): (...args) => Promise +function asyncThrottle(fn, initialOptions): (...args) => Promise> ``` -Defined in: [async-throttler.ts:223](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L223) +Defined in: [async-throttler.ts:281](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-throttler.ts#L281) Creates an async throttled function that limits how often the function can execute. The throttled function will execute at most once per wait period, even if called multiple times. If called while executing, it will wait until execution completes before scheduling the next call. +Unlike the non-async Throttler, this async version supports returning values from the throttled function, +making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call +instead of setting the result on a state variable from within the throttled function. + ## Type Parameters • **TFn** *extends* [`AnyAsyncFunction`](../type-aliases/anyasyncfunction.md) -• **TArgs** *extends* `any`[] - ## Parameters ### fn @@ -33,7 +35,7 @@ If called while executing, it will wait until execution completes before schedul ### initialOptions -`Omit`\<[`AsyncThrottlerOptions`](../interfaces/asyncthrottleroptions.md)\<`TFn`, `TArgs`\>, `"enabled"`\> +`Omit`\<[`AsyncThrottlerOptions`](../interfaces/asyncthrottleroptions.md)\<`TFn`\>, `"enabled"`\> ## Returns @@ -46,20 +48,21 @@ If a call is already in progress, it may be blocked or queued depending on the ` #### args -...`TArgs` +...`Parameters`\<`TFn`\> ### Returns -`Promise`\<`void`\> +`Promise`\<`undefined` \| `ReturnType`\<`TFn`\>\> ## Example ```ts -const throttled = asyncThrottle(async () => { - await someAsyncOperation(); +const throttled = asyncThrottle(async (value: string) => { + const result = await saveToAPI(value); + return result; // Return value is preserved }, { wait: 1000 }); // This will execute at most once per second -await throttled(); -await throttled(); // Waits 1 second before executing +// Returns the API response directly +const result = await throttled(inputElement.value); ``` diff --git a/docs/zh-hant/reference/functions/ratelimit.md b/docs/zh-hant/reference/functions/ratelimit.md index 449d8885b..695cfbc64 100644 --- a/docs/zh-hant/reference/functions/ratelimit.md +++ b/docs/zh-hant/reference/functions/ratelimit.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:04:17.648Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:45:08.632Z' id: rateLimit title: rateLimit --- @@ -13,7 +13,7 @@ title: rateLimit function rateLimit(fn, initialOptions): (...args) => boolean ``` -Defined in: [rate-limiter.ts:216](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L216) +Defined in: [rate-limiter.ts:252](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L252) Creates a rate-limited function that will execute the provided function up to a maximum number of times within a time window. @@ -22,6 +22,12 @@ Note that rate limiting is a simpler form of execution control compared to throt - A throttler ensures even spacing between executions, which can be better for consistent performance - A debouncer collapses multiple calls into one, which is better for handling bursts of events +The rate limiter supports two types of windows: +- 'fixed': A strict window that resets after the window period. All executions within the window count + towards the limit, and the window resets completely after the period. +- 'sliding': A rolling window that allows executions as old ones expire. This provides a more + consistent rate of execution over time. + Consider using throttle() or debounce() if you need more intelligent execution control. Use rate limiting when you specifically need to enforce a hard limit on the number of executions within a time period. @@ -71,10 +77,11 @@ rateLimiter.maybeExecute('arg1', 'arg2'); // false ## Example ```ts -// Rate limit to 5 calls per minute +// Rate limit to 5 calls per minute with a sliding window const rateLimited = rateLimit(makeApiCall, { limit: 5, window: 60000, + windowType: 'sliding', onReject: (rateLimiter) => { console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); } diff --git a/docs/zh-hant/reference/interfaces/asyncratelimiteroptions.md b/docs/zh-hant/reference/interfaces/asyncratelimiteroptions.md index b2caa2b18..e5de76d0b 100644 --- a/docs/zh-hant/reference/interfaces/asyncratelimiteroptions.md +++ b/docs/zh-hant/reference/interfaces/asyncratelimiteroptions.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:04:17.627Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:45:08.620Z' id: AsyncRateLimiterOptions title: AsyncRateLimiterOptions --- @@ -149,3 +149,18 @@ window: number; Defined in: [async-rate-limiter.ts:38](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L38) Time window in milliseconds within which the limit applies + +*** + +### windowType? + +```ts +optional windowType: "fixed" | "sliding"; +``` + +Defined in: [async-rate-limiter.ts:45](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/async-rate-limiter.ts#L45) + +Type of window to use for rate limiting +- 'fixed': Uses a fixed window that resets after the window period +- 'sliding': Uses a sliding window that allows executions as old ones expire +Defaults to 'fixed' diff --git a/docs/zh-hant/reference/interfaces/ratelimiteroptions.md b/docs/zh-hant/reference/interfaces/ratelimiteroptions.md index cf9bdaa75..5b06ee9af 100644 --- a/docs/zh-hant/reference/interfaces/ratelimiteroptions.md +++ b/docs/zh-hant/reference/interfaces/ratelimiteroptions.md @@ -1,6 +1,6 @@ --- -source-updated-at: '2025-05-05T07:34:55.000Z' -translation-updated-at: '2025-05-06T23:04:17.592Z' +source-updated-at: '2025-05-08T02:24:20.000Z' +translation-updated-at: '2025-05-08T05:45:08.616Z' id: RateLimiterOptions title: RateLimiterOptions --- @@ -97,3 +97,18 @@ window: number; Defined in: [rate-limiter.ts:27](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L27) Time window in milliseconds within which the limit applies + +*** + +### windowType? + +```ts +optional windowType: "fixed" | "sliding"; +``` + +Defined in: [rate-limiter.ts:34](https://github.com/TanStack/pacer/blob/main/packages/pacer/src/rate-limiter.ts#L34) + +Type of window to use for rate limiting +- 'fixed': Uses a fixed window that resets after the window period +- 'sliding': Uses a sliding window that allows executions as old ones expire +Defaults to 'fixed'