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

Batching-Anleitung

Batching 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 Konzept

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

  • Erreichen einer maximalen Batch-Größe
  • Warten einer maximalen Zeitspanne
  • Benutzerdefinierte Logik (z. B. ein spezielles Element oder eine Bedingung)

Batching Visualisierung

text
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

Wann Batching verwenden

Batching ist am besten geeignet, wenn

  • Die Verarbeitung von Elementen in Gruppen effizienter ist (z. B. Netzwerkanfragen, Datenbankschreibvorgänge)
  • Sie die Häufigkeit teurer Operationen reduzieren möchten
  • Sie die Rate oder Größe der Verarbeitung kontrollieren müssen
  • Sie Leistungsschübe in weniger Operationen umwandeln möchten

Wann Batching nicht verwenden

Batching ist möglicherweise nicht ideal, wenn

  • Jedes Element einzeln und sofort verarbeitet werden muss (verwenden Sie Queuing)
  • Sie nur am neuesten Wert interessiert sind (verwenden Sie Debouncing)

Tipp

Wenn Sie feststellen, dass Sie wiederholte Aufrufe tätigen, die gruppiert werden könnten, kann Batching Ihnen helfen, Leistung und Ressourcenverbrauch zu optimieren.

Batching in TanStack Pacer

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.

Grundlegende Verwendung mit batch

Die Funktion batch bietet eine einfache Möglichkeit, eine Batching-Funktion zu erstellen

ts
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.

Erweiterte Verwendung mit der Batcher-Klasse

Die Klasse Batcher bietet volle Kontrolle über das Batching-Verhalten

ts
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

Batcher-Optionen ermöglichen es Ihnen, anzupassen, wie und wann Batches verarbeitet werden

  • maxSize: Maximale Anzahl von Elementen pro Batch (Standard: Infinity)
  • wait: Maximale Zeit (ms), die vor der Verarbeitung eines Batches gewartet wird (Standard: Infinity)
  • getShouldExecute: Benutzerdefinierte Funktion zur Bestimmung, ob ein Batch verarbeitet werden soll
  • onExecute: Callback nach der Verarbeitung eines Batches
  • onItemsChange: Callback nach dem Hinzufügen von Elementen oder der Verarbeitung eines Batches
  • onIsRunningChange: Callback, wenn sich der Laufstatus des Batchers ändert
  • started: Ob der Batcher sofort zu laufen beginnt (Standard: true)

Batcher-Methoden

Die Klasse Batcher bietet mehrere Methoden zur Batch-Verwaltung

ts
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

Benutzerdefinierte Batch-Trigger

Sie können getShouldExecute verwenden, um einen Batch basierend auf benutzerdefinierter Logik auszulösen

ts
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

Dynamische Konfiguration

Sie können Batcher-Optionen zur Laufzeit aktualisieren

ts
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

Zustandsverwaltung

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.

Zustandsselektor (Framework-Adapter)

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.

ts
// 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
  })
)

Anfangszustand

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

ts
// 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
})

Zustandsänderungen abonnieren

Der Store ist reaktiv und unterstützt Abonnements

ts
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.

Verfügbare Zustandseigenschaften

Die BatcherState umfasst

  • executionCount: Anzahl der abgeschlossenen Batch-Ausführungen
  • isEmpty: Ob der Batcher keine Elemente zum Verarbeiten hat (Array von Elementen ist leer)
  • isPending: Gibt an, ob der Batcher auf den Timeout wartet, um die Stapelverarbeitung auszulösen
  • items: Array von Elementen, die derzeit zur Stapelverarbeitung in der Warteschlange stehen
  • size: Anzahl der Elemente, die sich derzeit in der Stapelwarteschlange befinden
  • status: Aktueller Verarbeitungsstatus ('idle' | 'pending')
  • totalItemsProcessed: Gesamtzahl der Elemente, die über alle Batches hinweg verarbeitet wurden

Auslösen ausstehender Batches

Der Batcher unterstützt das Auslösen ausstehender Batches, um die Verarbeitung sofort zu starten

ts
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)

Framework-Adapter

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.

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.