Alle Kernkonzepte aus dem Throttling Guide gelten auch für asynchrones Throttling.
Normalerweise können Sie einfach den normalen synchronen Throttler verwenden, und er funktioniert auch mit asynchronen Funktionen. Für fortgeschrittene Anwendungsfälle, wie z. B. wenn Sie den Rückgabewert einer gedrosselten Funktion verwenden möchten (anstatt nur einen setState-Nebeneffekt aufzurufen) oder Ihre Fehlerbehandlungslogik in den Throttler legen möchten, können Sie den asynchronen Throttler verwenden.
TanStack Pacer bietet asynchrones Throttling über die Klasse AsyncThrottler und die Funktion asyncThrottle.
Hier ist ein einfaches Beispiel, das zeigt, wie der asynchrone Throttler für eine Suchoperation verwendet wird
const throttledSearch = asyncThrottle(
async (searchTerm: string) => {
const results = await fetchSearchResults(searchTerm)
return results
},
{
wait: 500,
onSuccess: (results, args, throttler) => {
console.log('Search succeeded:', results)
console.log('Search arguments:', args)
},
onError: (error, args, throttler) => {
console.error('Search failed:', error)
console.log('Failed arguments:', args)
}
}
)
// Usage
try {
const results = await throttledSearch('query')
// Handle successful results
} catch (error) {
// Handle errors if no onError handler was provided
console.error('Search failed:', error)
}
const throttledSearch = asyncThrottle(
async (searchTerm: string) => {
const results = await fetchSearchResults(searchTerm)
return results
},
{
wait: 500,
onSuccess: (results, args, throttler) => {
console.log('Search succeeded:', results)
console.log('Search arguments:', args)
},
onError: (error, args, throttler) => {
console.error('Search failed:', error)
console.log('Failed arguments:', args)
}
}
)
// Usage
try {
const results = await throttledSearch('query')
// Handle successful results
} catch (error) {
// Handle errors if no onError handler was provided
console.error('Search failed:', error)
}
Hinweis: Bei der Verwendung von React bevorzugen Sie den Hook useAsyncThrottledCallback gegenüber der Funktion asyncThrottle für eine bessere Integration mit dem Lebenszyklus von React und die automatische Bereinigung.
Im Gegensatz zum synchronen Throttler, der void zurückgibt, ermöglicht die asynchrone Version, den Rückgabewert Ihrer gedrosselten Funktion zu erfassen und zu verwenden. Die Methode maybeExecute gibt ein Promise zurück, das mit dem Rückgabewert der Funktion aufgelöst wird. So können Sie auf das Ergebnis warten und es entsprechend behandeln.
Der asynchrone Throttler bietet robuste Fehlerbehandlungsfunktionen
Die Klasse AsyncThrottler unterstützt die folgenden Rückrufe:
Beispiel
const asyncThrottler = new AsyncThrottler(async (value) => {
await saveToAPI(value)
}, {
wait: 500,
onSuccess: (result, args, throttler) => {
// Called after each successful execution
console.log('Async function executed', throttler.store.state.successCount)
console.log('Executed arguments:', args)
},
onSettled: (args, throttler) => {
// Called after each execution attempt
console.log('Async function settled', throttler.store.state.settleCount)
console.log('Settled arguments:', args)
},
onError: (error, args, throttler) => {
// Called if the async function throws an error
console.error('Async function failed:', error)
console.log('Failed arguments:', args)
}
})
const asyncThrottler = new AsyncThrottler(async (value) => {
await saveToAPI(value)
}, {
wait: 500,
onSuccess: (result, args, throttler) => {
// Called after each successful execution
console.log('Async function executed', throttler.store.state.successCount)
console.log('Executed arguments:', args)
},
onSettled: (args, throttler) => {
// Called after each execution attempt
console.log('Async function settled', throttler.store.state.settleCount)
console.log('Settled arguments:', args)
},
onError: (error, args, throttler) => {
// Called if the async function throws an error
console.error('Async function failed:', error)
console.log('Failed arguments:', args)
}
})
Da die Methode maybeExecute des Throttlers ein Promise zurückgibt, können Sie wählen, jede Ausführung abzuwarten, bevor Sie die nächste starten. Dies gibt Ihnen die Kontrolle über die Ausführungsreihenfolge und stellt sicher, dass jeder Aufruf die aktuellsten Daten verarbeitet. Dies ist besonders nützlich, wenn Sie mit Operationen zu tun haben, die von den Ergebnissen früherer Aufrufe abhängen, oder wenn die Aufrechterhaltung der Datenkonsistenz entscheidend ist.
Wenn Sie beispielsweise das Profil eines Benutzers aktualisieren und dann sofort dessen aktualisierte Daten abrufen, können Sie die Aktualisierungsoperation awaiten, bevor Sie den Abruf starten.
Genau wie der synchrone Throttler unterstützt der asynchrone Throttler dynamische Optionen für wait und enabled, die Funktionen sein können, die die Throttler-Instanz erhalten. Dies ermöglicht ein hochentwickeltes, laufzeitadaptives Throttling-Verhalten.
Der asynchrone Throttler unterstützt das Leeren ausstehender Ausführungen, um sie sofort auszulösen
const asyncThrottler = new AsyncThrottler(asyncFn, { wait: 1000 })
asyncThrottler.maybeExecute('some-arg')
console.log(asyncThrottler.store.state.isPending) // true
// Flush immediately instead of waiting
asyncThrottler.flush()
console.log(asyncThrottler.store.state.isPending) // false
const asyncThrottler = new AsyncThrottler(asyncFn, { wait: 1000 })
asyncThrottler.maybeExecute('some-arg')
console.log(asyncThrottler.store.state.isPending) // true
// Flush immediately instead of waiting
asyncThrottler.flush()
console.log(asyncThrottler.store.state.isPending) // false
Die Klasse AsyncThrottler verwendet TanStack Store für reaktives Zustandsmanagement und bietet Echtzeit-Zugriff auf den Ausführungsstatus, die Fehlerverfolgung und Zeitinformationen. Der gesamte Zustand wird in einem TanStack Store gespeichert und kann über asyncThrottler.store.state abgerufen werden. Wenn Sie jedoch einen Framework-Adapter wie React oder Solid verwenden, sollten Sie den Zustand nicht von hier abrufen. Stattdessen lesen Sie den Zustand aus asyncThrottler.state und stellen eine Selektor-Callback als 3. Argument für den Hook useAsyncThrottler bereit, um die Zustandsverfolgung zu aktivieren, wie unten gezeigt.
Framework-Adapter unterstützen ein selector-Argument, das es Ihnen ermöglicht, anzugeben, welche Zustandsänderungen Neu-Renderings auslösen. Dies optimiert die Leistung, indem unnötige Neu-Renderings bei irrelevanten Zustandsänderungen verhindert werden.
Standardmäßig ist throttler.state leer ({}), da der Selektor standardmäßig leer ist. Hier wird reaktiver Zustand von einem TanStack Store useStore gespeichert. Sie müssen die Zustandsverfolgung aktivieren, indem Sie eine Selektorfunktion bereitstellen.
// Default behavior - no reactive state subscriptions
const asyncThrottler = useAsyncThrottler(asyncFn, { wait: 500 })
console.log(asyncThrottler.state) // {}
// Opt-in to re-render when isExecuting changes
const asyncThrottler = useAsyncThrottler(
asyncFn,
{ wait: 500 },
(state) => ({ isExecuting: state.isExecuting })
)
console.log(asyncThrottler.state.isExecuting) // Reactive value
// Multiple state properties
const asyncThrottler = useAsyncThrottler(
asyncFn,
{ wait: 500 },
(state) => ({
isExecuting: state.isExecuting,
successCount: state.successCount,
errorCount: state.errorCount
})
)
// Default behavior - no reactive state subscriptions
const asyncThrottler = useAsyncThrottler(asyncFn, { wait: 500 })
console.log(asyncThrottler.state) // {}
// Opt-in to re-render when isExecuting changes
const asyncThrottler = useAsyncThrottler(
asyncFn,
{ wait: 500 },
(state) => ({ isExecuting: state.isExecuting })
)
console.log(asyncThrottler.state.isExecuting) // Reactive value
// Multiple state properties
const asyncThrottler = useAsyncThrottler(
asyncFn,
{ wait: 500 },
(state) => ({
isExecuting: state.isExecuting,
successCount: state.successCount,
errorCount: state.errorCount
})
)
Sie können anfängliche Zustandswerte beim Erstellen eines asynchronen Throttlers angeben. Dies wird häufig verwendet, um Zustände aus persistentem Speicher wiederherzustellen
// Load initial state from localStorage
const savedState = localStorage.getItem('async-throttler-state')
const initialState = savedState ? JSON.parse(savedState) : {}
const asyncThrottler = new AsyncThrottler(asyncFn, {
wait: 500,
initialState
})
// Load initial state from localStorage
const savedState = localStorage.getItem('async-throttler-state')
const initialState = savedState ? JSON.parse(savedState) : {}
const asyncThrottler = new AsyncThrottler(asyncFn, {
wait: 500,
initialState
})
Der Store ist reaktiv und unterstützt Abonnements
const asyncThrottler = new AsyncThrottler(asyncFn, { wait: 500 })
// Subscribe to state changes
const unsubscribe = asyncThrottler.store.subscribe((state) => {
// do something with the state like persist it to localStorage
})
// Unsubscribe when done
unsubscribe()
const asyncThrottler = new AsyncThrottler(asyncFn, { wait: 500 })
// Subscribe to state changes
const unsubscribe = asyncThrottler.store.subscribe((state) => {
// do something with the state like persist it to localStorage
})
// Unsubscribe when done
unsubscribe()
Hinweis: Dies ist unnötig, wenn Sie einen Framework-Adapter verwenden, da der zugrunde liegende Hook useStore dies bereits tut. Sie können auch useStore von TanStack Store importieren und verwenden, um throttler.store.state mit einem benutzerdefinierten Selektor zu einem reaktiven Zustand zu machen, wo immer Sie ihn benötigen.
Die Klasse AsyncThrottlerState beinhaltet
Jeder Framework-Adapter bietet Hooks, die auf der Kernfunktionalität des asynchronen Throttlings aufbauen, um sich in das Zustandsmanagementsystem des Frameworks zu integrieren. Hooks wie createAsyncThrottler, useAsyncThrottledCallback oder ähnliche sind für jedes Framework verfügbar.
Für Kernkonzepte des Throttlings und synchrones Throttling siehe den Throttling Guide.
Ihre wöchentliche Dosis JavaScript-Nachrichten. Jeden Montag kostenlos an über 100.000 Entwickler geliefert.