Framework
Version
Debouncer API Referenz
Throttler API Referenz
Rate Limiter API Referenz
Queue API Referenz
Batcher API Referenz

useAsyncRateLimiter

Funktion: useAsyncRateLimiter()

ts
function useAsyncRateLimiter<TFn, TSelected>(
   fn, 
   options, 
selector): ReactAsyncRateLimiter<TFn, TSelected>
function useAsyncRateLimiter<TFn, TSelected>(
   fn, 
   options, 
selector): ReactAsyncRateLimiter<TFn, TSelected>

Definiert in: react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts:178

Ein Low-Level React-Hook, der eine AsyncRateLimiter-Instanz erstellt, um zu begrenzen, wie oft eine asynchrone Funktion innerhalb eines Zeitfensters ausgeführt werden kann.

Dieser Hook ist flexibel und unabhängig von der Zustandsverwaltung konzipiert – er gibt einfach eine Rate-Limiter-Instanz zurück, die Sie mit jeder Zustandsverwaltungs-Lösung integrieren können (useState, Redux, Zustand, Jotai usw.).

Ratenbegrenzung ermöglicht es einer asynchronen Funktion, bis zu einem bestimmten Limit innerhalb eines Zeitfensters ausgeführt zu werden, und blockiert dann nachfolgende Aufrufe, bis das Fenster abgelaufen ist. Dies ist nützlich, um API-Ratenlimits einzuhalten, Ressourcenbeschränkungen zu verwalten oder Bursts von asynchronen Operationen zu steuern.

Im Gegensatz zum nicht-asynchronen RateLimiter unterstützt diese asynchrone Version das Zurückgeben von Werten aus der ratenbegrenzten Funktion, was sie ideal für API-Aufrufe und andere asynchrone Operationen macht, bei denen Sie das Ergebnis des Aufrufs maybeExecute anstelle der Festlegung des Ergebnisses in einer Zustandsvariablen innerhalb der ratenbegrenzten Funktion wünschen.

Der Ratenbegrenzer unterstützt zwei Arten von Fenstern

  • 'fixed': Ein striktes Fenster, das nach Ablauf des Zeitfensters zurückgesetzt wird. Alle Ausführungen innerhalb des Fensters zählen für das Limit, und das Fenster wird nach Ablauf der Periode vollständig zurückgesetzt.
  • 'sliding': Ein rollierendes Fenster, das Ausführungen ermöglicht, sobald ältere abgelaufen sind. Dies sorgt für eine konsistentere Ausführungsrate im Laufe der Zeit.

Fehlerbehandlung

  • Wenn ein onError-Handler bereitgestellt wird, wird dieser mit dem Fehler und der Ratenbegrenzerinstanz aufgerufen
  • Wenn throwOnError auf true gesetzt ist (Standardwert, wenn kein onError-Handler bereitgestellt wird), wird der Fehler ausgelöst.
  • Wenn throwOnError auf false gesetzt ist (Standardwert, wenn ein onError-Handler bereitgestellt wird), wird der Fehler "verschluckt".
  • Sowohl onError als auch throwOnError können zusammen verwendet werden – der Handler wird aufgerufen, bevor ein Fehler ausgelöst wird.
  • Der Fehlerzustand kann mit der zugrunde liegenden AsyncRateLimiter-Instanz überprüft werden
  • Ratenlimit-Zurückweisungen (wenn das Limit überschritten wird) werden getrennt von Ausführungsfehlern über den onReject-Handler behandelt

Zustandsverwaltung und Selektor

Der Hook verwendet TanStack Store für reaktives Zustandsmanagement. Der Parameter selector ermöglicht es Ihnen anzugeben, welche Zustandsänderungen ein erneutes Rendern auslösen, wodurch die Leistung optimiert wird, indem unnötige erneute Renderings verhindert werden, wenn irrelevante Zustandsänderungen auftreten.

Standardmäßig erfolgen keine reaktiven Zustands-Subscriptions und Sie müssen das Zustands-Tracking durch Bereitstellen einer Selector-Funktion aktivieren. Dies verhindert unnötige Renderings und gibt Ihnen die volle Kontrolle darüber, wann Ihre Komponente aktualisiert wird. Nur wenn Sie einen Selector bereitstellen, wird die Komponente neu gerendert, wenn sich die ausgewählten Zustandswerte ändern.

Verfügbare Zustandseigenschaften

  • errorCount: Anzahl der Funktionsausführungen, die zu Fehlern geführt haben
  • executionTimes: Array von Zeit­stempeln, wann Ausführungen für Raten­begrenzungs­berechnungen stattfanden
  • isExecuting: Ob die ratenbegrenzte Funktion gerade asynchron ausgeführt wird
  • lastResult: Das Ergebnis der letzten erfolgreichen Funktionsausführung
  • rejectionCount: Anzahl der Funktions­ausführungen, die aufgrund von Raten­begrenzung abgelehnt wurden
  • settleCount: Anzahl der abgeschlossenen Funktionsausführungen (Erfolg oder Fehler)
  • successCount: Anzahl der Funktionsausführungen, die erfolgreich abgeschlossen wurden

Typparameter

TFn extends AnyAsyncFunction

TSelected = {}

Parameter

fn

TFn

optionen

AsyncRateLimiterOptions<TFn>

selector

(state) => TSelected

Gibt zurück

ReactAsyncRateLimiter<TFn, TSelected>

Beispiel

tsx
// Default behavior - no reactive state subscriptions
const asyncRateLimiter = useAsyncRateLimiter(
  async (id: string) => {
    const data = await api.fetchData(id);
    return data; // Return value is preserved
  },
  { limit: 5, window: 1000 } // 5 calls per second
);

// Opt-in to re-render when execution state changes (optimized for loading indicators)
const asyncRateLimiter = useAsyncRateLimiter(
  async (id: string) => {
    const data = await api.fetchData(id);
    return data;
  },
  { limit: 5, window: 1000 },
  (state) => ({ isExecuting: state.isExecuting })
);

// Opt-in to re-render when results are available (optimized for data display)
const asyncRateLimiter = useAsyncRateLimiter(
  async (id: string) => {
    const data = await api.fetchData(id);
    return data;
  },
  { limit: 5, window: 1000 },
  (state) => ({
    lastResult: state.lastResult,
    successCount: state.successCount
  })
);

// Opt-in to re-render when error/rejection state changes (optimized for error handling)
const asyncRateLimiter = useAsyncRateLimiter(
  async (id: string) => {
    const data = await api.fetchData(id);
    return data;
  },
  {
    limit: 5,
    window: 1000,
    onError: (error) => console.error('API call failed:', error),
    onReject: (rateLimiter) => console.log('Rate limit exceeded')
  },
  (state) => ({
    errorCount: state.errorCount,
    rejectionCount: state.rejectionCount
  })
);

// Opt-in to re-render when execution metrics change (optimized for stats display)
const asyncRateLimiter = useAsyncRateLimiter(
  async (id: string) => {
    const data = await api.fetchData(id);
    return data;
  },
  { limit: 5, window: 1000 },
  (state) => ({
    successCount: state.successCount,
    errorCount: state.errorCount,
    settleCount: state.settleCount,
    rejectionCount: state.rejectionCount
  })
);

// Opt-in to re-render when execution times change (optimized for window calculations)
const asyncRateLimiter = useAsyncRateLimiter(
  async (id: string) => {
    const data = await api.fetchData(id);
    return data;
  },
  { limit: 5, window: 1000 },
  (state) => ({ executionTimes: state.executionTimes })
);

// With state management and return value
const [data, setData] = useState(null);
const { maybeExecute, state } = useAsyncRateLimiter(
  async (query) => {
    const result = await searchAPI(query);
    setData(result);
    return result; // Return value can be used by the caller
  },
  {
    limit: 10,
    window: 60000, // 10 calls per minute
    onReject: (rateLimiter) => {
      console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`);
    },
    onError: (error) => {
      console.error('API call failed:', error);
    }
  }
);

// Access the selected state (will be empty object {} unless selector provided)
const { isExecuting, lastResult, rejectionCount } = state;
// Default behavior - no reactive state subscriptions
const asyncRateLimiter = useAsyncRateLimiter(
  async (id: string) => {
    const data = await api.fetchData(id);
    return data; // Return value is preserved
  },
  { limit: 5, window: 1000 } // 5 calls per second
);

// Opt-in to re-render when execution state changes (optimized for loading indicators)
const asyncRateLimiter = useAsyncRateLimiter(
  async (id: string) => {
    const data = await api.fetchData(id);
    return data;
  },
  { limit: 5, window: 1000 },
  (state) => ({ isExecuting: state.isExecuting })
);

// Opt-in to re-render when results are available (optimized for data display)
const asyncRateLimiter = useAsyncRateLimiter(
  async (id: string) => {
    const data = await api.fetchData(id);
    return data;
  },
  { limit: 5, window: 1000 },
  (state) => ({
    lastResult: state.lastResult,
    successCount: state.successCount
  })
);

// Opt-in to re-render when error/rejection state changes (optimized for error handling)
const asyncRateLimiter = useAsyncRateLimiter(
  async (id: string) => {
    const data = await api.fetchData(id);
    return data;
  },
  {
    limit: 5,
    window: 1000,
    onError: (error) => console.error('API call failed:', error),
    onReject: (rateLimiter) => console.log('Rate limit exceeded')
  },
  (state) => ({
    errorCount: state.errorCount,
    rejectionCount: state.rejectionCount
  })
);

// Opt-in to re-render when execution metrics change (optimized for stats display)
const asyncRateLimiter = useAsyncRateLimiter(
  async (id: string) => {
    const data = await api.fetchData(id);
    return data;
  },
  { limit: 5, window: 1000 },
  (state) => ({
    successCount: state.successCount,
    errorCount: state.errorCount,
    settleCount: state.settleCount,
    rejectionCount: state.rejectionCount
  })
);

// Opt-in to re-render when execution times change (optimized for window calculations)
const asyncRateLimiter = useAsyncRateLimiter(
  async (id: string) => {
    const data = await api.fetchData(id);
    return data;
  },
  { limit: 5, window: 1000 },
  (state) => ({ executionTimes: state.executionTimes })
);

// With state management and return value
const [data, setData] = useState(null);
const { maybeExecute, state } = useAsyncRateLimiter(
  async (query) => {
    const result = await searchAPI(query);
    setData(result);
    return result; // Return value can be used by the caller
  },
  {
    limit: 10,
    window: 60000, // 10 calls per minute
    onReject: (rateLimiter) => {
      console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`);
    },
    onError: (error) => {
      console.error('API call failed:', error);
    }
  }
);

// Access the selected state (will be empty object {} unless selector provided)
const { isExecuting, lastResult, rejectionCount } = state;
Unsere Partner
Code Rabbit
Unkey
Bytes abonnieren

Ihre wöchentliche Dosis JavaScript-Nachrichten. Jeden Montag kostenlos an über 100.000 Entwickler geliefert.

Bytes

Kein Spam. Jederzeit kündbar.

Bytes abonnieren

Ihre wöchentliche Dosis JavaScript-Nachrichten. Jeden Montag kostenlos an über 100.000 Entwickler geliefert.

Bytes

Kein Spam. Jederzeit kündbar.