Batch, Dispose e Demo Completa
Nesta página
Batch
Por padrão, cada .set() dispara os effects imediatamente. signal_batch(|| { ... })
adia todos os effects até o fechamento terminar, executando-os uma única vez com
o estado final. Isso evita renders intermediários desnecessários em atualizações que
afetam vários signals ao mesmo tempo.
Dois .set() dentro do batch resultam em apenas uma execução do 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 retorna um handle. Chamando handle.dispose(), o effect é removido de
todos os subscribers e nunca mais dispara. Use em componentes desmontados,
cancelamentos ou para liberar memória em apps de longa duração.
Após .dispose(), escritas ao signal não produzem saída.
// 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
Com os três primitivos dominados — signal, computed e effect — é possível
construir pipelines reativos expressivos. O exemplo abaixo compõe tudo junto,
incluindo signal_batch para uma atualização atômica:
Pipeline completa: dois computeds derivados de um signal, effect unificado e 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)
Desafio
Estenda a demo completa adicionando um effect secundário que imprime apenas quando
parity muda de "par" para "ímpar" (use um signal auxiliar para guardar o último valor).
Veja também