Batch, Dispose y Demo Completa
En esta página
Batch
Por defecto, cada .set() dispara los effects inmediatamente. signal_batch(|| { ... })
aplaza todos los effects hasta que el cierre termine, ejecutándolos una sola vez con
el estado final. Esto evita renders intermedios innecesarios en actualizaciones que
afectan a varios signals al mismo tiempo.
Dos .set() dentro del batch resultan en una sola ejecución del effect.
// Feature: signal_batch — coalesce multiple writes into one effect run
// Syntax: `signal_batch(|| { ... multiple Signal.set calls ... })`.
// Effects depending on any of the changed signals run once at the
// end of the batch, not after each individual set.
// When to use: animation frames, bulk imports, transactions where
// intermediate states are noise.
use std::reactive::Signal
let x = signal(0)
let y = signal(0)
let runs = signal(0)
let e = effect(|| {
print("x={x.get()} y={y.get()}")
// `peek` reads without tracking, so this self-write does not
// re-trigger the effect.
runs.set(runs.peek() + 1)
})
// expected: x=0 y=0 (initial run)
// Without batch, this would print twice. With batch, it prints once.
signal_batch(|| {
x.set(10)
y.set(20)
})
// expected: x=10 y=20
print("effect runs: {runs.peek()}")
// expected: effect runs: 2 (initial + one batched)
Dispose
effect devuelve un handle. Llamando a handle.dispose(), el effect es eliminado de
todos los suscriptores y nunca más se dispara. Úsalo en componentes desmontados,
cancelaciones o para liberar memoria en apps de larga duración.
Después de .dispose(), las escrituras al signal no producen salida.
// Feature: effect.dispose() — unsubscribe an effect from all its signals
// Syntax: `let e = effect(|| { ... }); e.dispose()`.
// When to use: component unmount, cancellation, freeing memory in
// long-running apps. After dispose, the effect never fires again.
use std::reactive::Signal
let count = signal(0)
let e = effect(|| {
print("count = {count.get()}")
})
// expected: count = 0
count.set(1)
// expected: count = 1
e.dispose()
// After dispose, sets do nothing visible — the effect is gone.
count.set(2)
count.set(3)
print("done")
// expected: done
Demo Completa
Con los tres primitivos dominados — signal, computed y effect — es posible
construir pipelines reactivos expresivos. El ejemplo a continuación compone todo junto,
incluyendo signal_batch para una actualización atómica:
Pipeline completa: dos computeds derivados de un signal, effect unificado y batch.
// Feature: Putting it all together — signal + computed + effect
// A compact reactive pipeline showing how the three primitives
// compose. Read this file last; the others isolate each piece.
use std::reactive::Signal
let count = signal(0)
let doubled = computed(|| { count.get() * 2 })
let parity = computed(|| {
if count.get() % 2 == 0 { return "even" }
return "odd"
})
let e = effect(|| {
print("count={count.get()} doubled={doubled.get()} ({parity.get()})")
})
// expected: count=0 doubled=0 (even)
// Single batched update — effect fires once at the end.
signal_batch(|| {
count.set(3)
})
// expected: count=3 doubled=6 (odd)
count.set(10)
// expected: count=10 doubled=20 (even)
Desafío
Extiende la demo completa añadiendo un effect secundario que imprima solo cuando
parity cambia de "par" a "impar" (usa un signal auxiliar para guardar el último valor).
Consulta también