Saltar al contenido

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.

05-batch.zolo
Playground
// 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.

06-dispose.zolo
Playground
// 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.

08-full-demo.zolo
Playground
// 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).

Buscar en Zolo

9 resultados

enespt-br