batchBatcher-KlasseBatching ist eine leistungsstarke Technik, um mehrere Operationen zu gruppieren und sie als eine einzige Einheit zu verarbeiten. Im Gegensatz zu Queuing, das sicherstellt, dass jede Operation einzeln verarbeitet wird, sammelt Batching Elemente und verarbeitet sie in konfigurierbaren Gruppen, was die Effizienz verbessert und den Overhead reduziert. Dieser Leitfaden behandelt die Batching-Konzepte von TanStack Pacer.
Batching sammelt Elemente über einen bestimmten Zeitraum oder bis eine bestimmte Größe erreicht ist und verarbeitet sie dann auf einmal. Dies ist ideal für Szenarien, in denen die Verarbeitung von Elementen in großen Mengen effizienter ist als die einzelne Handhabung. Batching kann ausgelöst werden durch
Batching (processing every 3 items or every 2 seconds)
Timeline: [1 second per tick]
Calls: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️
Batch: [ABC] [] [DE] [] [FGH] []
Executed: ✅ ✅ ✅
[===============================]
^ Items are grouped and processed together
[Items accumulate] [Process batch] [Empty]
in batch as group batch
Batching (processing every 3 items or every 2 seconds)
Timeline: [1 second per tick]
Calls: ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️
Batch: [ABC] [] [DE] [] [FGH] []
Executed: ✅ ✅ ✅
[===============================]
^ Items are grouped and processed together
[Items accumulate] [Process batch] [Empty]
in batch as group batch
Batching ist am besten geeignet, wenn
Batching ist möglicherweise nicht ideal, wenn
Tipp
Wenn Sie feststellen, dass Sie wiederholte Aufrufe tätigen, die gruppiert werden könnten, kann Batching Ihnen helfen, Leistung und Ressourcenverbrauch zu optimieren.
TanStack Pacer bietet Batching durch die Klasse Batcher und die einfache Funktion batch. Beide ermöglichen es Ihnen, Elemente zu sammeln und sie in konfigurierbaren Batches zu verarbeiten.
Die Funktion batch bietet eine einfache Möglichkeit, eine Batching-Funktion zu erstellen
import { batch } from '@tanstack/pacer'
// Create a batcher that processes up to 3 items or every 2 seconds
const processBatch = batch<number>(
(items) => {
// Process the batch
console.log('Processing batch:', items)
},
{
maxSize: 3, // Process when 3 items are collected
wait: 2000, // Or after 2 seconds, whichever comes first
onItemsChange: (batcher) => {
console.log('Current batch:', batcher.peekAllItems())
}
}
)
// Add items to be batched
processBatch(1)
processBatch(2)
processBatch(3) // Triggers batch processing
processBatch(4)
// Or wait 2 seconds for the next batch to process
import { batch } from '@tanstack/pacer'
// Create a batcher that processes up to 3 items or every 2 seconds
const processBatch = batch<number>(
(items) => {
// Process the batch
console.log('Processing batch:', items)
},
{
maxSize: 3, // Process when 3 items are collected
wait: 2000, // Or after 2 seconds, whichever comes first
onItemsChange: (batcher) => {
console.log('Current batch:', batcher.peekAllItems())
}
}
)
// Add items to be batched
processBatch(1)
processBatch(2)
processBatch(3) // Triggers batch processing
processBatch(4)
// Or wait 2 seconds for the next batch to process
Hinweis: Bei Verwendung von React bevorzugen Sie den Hook useBatchedCallback gegenüber der Funktion batch für eine bessere Integration mit dem Lebenszyklus von React und zur automatischen Bereinigung.
Die Funktion batch gibt eine Funktion zurück, die Elemente zum Batch hinzufügt. Batches werden automatisch basierend auf Ihrer Konfiguration verarbeitet.
Die Klasse Batcher bietet volle Kontrolle über das Batching-Verhalten
import { Batcher } from '@tanstack/pacer'
// Create a batcher that processes up to 5 items or every 3 seconds
const batcher = new Batcher<number>(
(items) => {
// Process the batch
console.log('Processing batch:', items)
},
{
maxSize: 5, // Process when 5 items are collected
wait: 3000, // Or after 3 seconds
getShouldExecute: (items, batcher) => items.includes(42), // Custom trigger
onItemsChange: (batcher) => {
console.log('Current batch:', batcher.peekAllItems())
}
}
)
// Add items to the batch
batcher.addItem(1)
batcher.addItem(2)
batcher.addItem(3)
// ...
// Manually process the current batch
batcher.execute()
// Control batching
batcher.stop() // Pause batching
batcher.start() // Resume batching
import { Batcher } from '@tanstack/pacer'
// Create a batcher that processes up to 5 items or every 3 seconds
const batcher = new Batcher<number>(
(items) => {
// Process the batch
console.log('Processing batch:', items)
},
{
maxSize: 5, // Process when 5 items are collected
wait: 3000, // Or after 3 seconds
getShouldExecute: (items, batcher) => items.includes(42), // Custom trigger
onItemsChange: (batcher) => {
console.log('Current batch:', batcher.peekAllItems())
}
}
)
// Add items to the batch
batcher.addItem(1)
batcher.addItem(2)
batcher.addItem(3)
// ...
// Manually process the current batch
batcher.execute()
// Control batching
batcher.stop() // Pause batching
batcher.start() // Resume batching
Batcher-Optionen ermöglichen es Ihnen, anzupassen, wie und wann Batches verarbeitet werden
Die Klasse Batcher bietet mehrere Methoden zur Batch-Verwaltung
batcher.addItem(item) // Add an item to the batch
batcher.execute() // Manually process the current batch
batcher.stop() // Pause batching
batcher.start() // Resume batching
batcher.store.state.size // Get current batch size
batcher.store.state.isEmpty // Check if batch is empty
batcher.store.state.isRunning // Check if batcher is running
batcher.peekAllItems() // Get all items in the current batch
batcher.store.state.executionCount // Number of batches processed
batcher.store.state.totalItemsProcessed // Number of items processed
batcher.setOptions(opts) // Update batcher options
batcher.flush() // Flush pending batch immediately
batcher.addItem(item) // Add an item to the batch
batcher.execute() // Manually process the current batch
batcher.stop() // Pause batching
batcher.start() // Resume batching
batcher.store.state.size // Get current batch size
batcher.store.state.isEmpty // Check if batch is empty
batcher.store.state.isRunning // Check if batcher is running
batcher.peekAllItems() // Get all items in the current batch
batcher.store.state.executionCount // Number of batches processed
batcher.store.state.totalItemsProcessed // Number of items processed
batcher.setOptions(opts) // Update batcher options
batcher.flush() // Flush pending batch immediately
Sie können getShouldExecute verwenden, um einen Batch basierend auf benutzerdefinierter Logik auszulösen
const batcher = new Batcher<number>(
(items) => console.log('Processing batch:', items),
{
getShouldExecute: (items) => items.includes(99),
}
)
batcher.addItem(1)
batcher.addItem(99) // Triggers batch processing immediately
const batcher = new Batcher<number>(
(items) => console.log('Processing batch:', items),
{
getShouldExecute: (items) => items.includes(99),
}
)
batcher.addItem(1)
batcher.addItem(99) // Triggers batch processing immediately
Sie können Batcher-Optionen zur Laufzeit aktualisieren
batcher.setOptions({
maxSize: 10,
wait: 1000,
})
const options = batcher.getOptions()
console.log(options.maxSize) // 10
batcher.setOptions({
maxSize: 10,
wait: 1000,
})
const options = batcher.getOptions()
console.log(options.maxSize) // 10
Die Klasse Batcher verwendet TanStack Store für reaktives State-Management und bietet Echtzeit-Zugriff auf den Batch-Status, die Ausführungszähler und den Verarbeitungsstatus. Der gesamte Status wird in einem TanStack Store gespeichert und kann über batcher.store.state abgerufen werden. Wenn Sie jedoch einen Framework-Adapter wie React oder Solid verwenden, sollten Sie den Status nicht von hier abrufen. Stattdessen lesen Sie den Status aus batcher.state und stellen einen Selektor-Callback als 3. Argument für den Hook useBatcher bereit, um sich für die Statusverfolgung zu entscheiden, 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 batcher.state leer ({}), da der Selektor standardmäßig leer ist. Hier werden reaktive Zustände von einem TanStack Store useStore gespeichert. Sie müssen sich für die Statusverfolgung entscheiden, indem Sie eine Selektor-Funktion bereitstellen.
// Default behavior - no reactive state subscriptions
const batcher = useBatcher(processFn, { maxSize: 5, wait: 1000 })
console.log(batcher.state) // {}
// Opt-in to re-render when size changes
const batcher = useBatcher(
processFn,
{ maxSize: 5, wait: 1000 },
(state) => ({ size: state.size })
)
console.log(batcher.state.size) // Reactive value
// Multiple state properties
const batcher = useBatcher(
processFn,
{ maxSize: 5, wait: 1000 },
(state) => ({
size: state.size,
executionCount: state.executionCount,
status: state.status
})
)
// Default behavior - no reactive state subscriptions
const batcher = useBatcher(processFn, { maxSize: 5, wait: 1000 })
console.log(batcher.state) // {}
// Opt-in to re-render when size changes
const batcher = useBatcher(
processFn,
{ maxSize: 5, wait: 1000 },
(state) => ({ size: state.size })
)
console.log(batcher.state.size) // Reactive value
// Multiple state properties
const batcher = useBatcher(
processFn,
{ maxSize: 5, wait: 1000 },
(state) => ({
size: state.size,
executionCount: state.executionCount,
status: state.status
})
)
Sie können Anfangswerte für den Status beim Erstellen eines Batchers angeben. Dies wird häufig verwendet, um den Status aus persistentem Speicher wiederherzustellen
// Load initial state from localStorage
const savedState = localStorage.getItem('batcher-state')
const initialState = savedState ? JSON.parse(savedState) : {}
const batcher = new Batcher(processFn, {
maxSize: 5,
wait: 1000,
initialState
})
// Load initial state from localStorage
const savedState = localStorage.getItem('batcher-state')
const initialState = savedState ? JSON.parse(savedState) : {}
const batcher = new Batcher(processFn, {
maxSize: 5,
wait: 1000,
initialState
})
Der Store ist reaktiv und unterstützt Abonnements
const batcher = new Batcher(processFn, { maxSize: 5, wait: 1000 })
// Subscribe to state changes
const unsubscribe = batcher.store.subscribe((state) => {
// do something with the state like persist it to localStorage
})
// Unsubscribe when done
unsubscribe()
const batcher = new Batcher(processFn, { maxSize: 5, wait: 1000 })
// Subscribe to state changes
const unsubscribe = batcher.store.subscribe((state) => {
// do something with the state like persist it to localStorage
})
// Unsubscribe when done
unsubscribe()
Hinweis: Dies ist nicht notwendig, wenn ein Framework-Adapter verwendet wird, da der zugrunde liegende Hook useStore dies bereits tut. Sie können auch useStore von TanStack Store importieren und verwenden, um batcher.store.state mit einem benutzerdefinierten Selektor zu reaktivem Status zu machen, wo immer Sie ihn benötigen.
Die BatcherState umfasst
Der Batcher unterstützt das Auslösen ausstehender Batches, um die Verarbeitung sofort zu starten
const batcher = new Batcher(processFn, { maxSize: 10, wait: 5000 })
batcher.addItem('item1')
batcher.addItem('item2')
console.log(batcher.store.state.isPending) // true
// Flush immediately instead of waiting
batcher.flush()
console.log(batcher.store.state.isEmpty) // true (batch was processed)
const batcher = new Batcher(processFn, { maxSize: 10, wait: 5000 })
batcher.addItem('item1')
batcher.addItem('item2')
console.log(batcher.store.state.isPending) // true
// Flush immediately instead of waiting
batcher.flush()
console.log(batcher.store.state.isEmpty) // true (batch was processed)
Jeder Framework-Adapter baut praktische Hooks und Funktionen um die Batcher-Klassen herum auf. Hooks wie useBatcher oder createBatcher sind kleine Wrapper, die den für gängige Anwendungsfälle erforderlichen Boilerplate-Code reduzieren können.
Für asynchrones Batching siehe den Async Batching Guide.
Ihre wöchentliche Dosis JavaScript-Nachrichten. Jeden Montag kostenlos an über 100.000 Entwickler geliefert.