Pular para o conteúdo

Efeitos e propagação

O efeito que roda ao nascer, o lote, e o losango que entregava um valor que nunca existiu.

O efeito roda uma vez ao ser criado#

dataforge
action mostrar():
    linhas.append($"total R$ {total.ler()}")

steady vigia := R.efeito(mostrar)   // ja rodou uma vez

itens.escrever([...])               // roda de novo
vigia.parar()                       // e para de rodar

Sem isso, quem escreve R.efeito(…) vê a tela vazia até a primeira mudança — e conclui que o efeito não funciona. A alternativa seria chamá-lo à mão depois de criar, o que se esquece exatamente uma vez.

A propagação tem duas fases#

Esta é a decisão que mais importa do módulo, e ela veio de um defeito medido. Num losangoca e b, e ba — marcar e avisar numa fase só entrega um valor que nunca existiu.

dataforge
a := R.sinal(1)
b := R.derivado(lambda => a.ler() * 2)
c := R.derivado(lambda => a.ler() + b.ler())

R.efeito(lambda => vistos.append(c.ler()))
a.escrever(5)

// antes:  [3, 7, 15]     <- o 7 nunca foi verdade
// agora:  [3, 15]

Hoje a marcação percorre o grafo inteiro primeiro, e só depois os efeitos e ouvintes rodam. Daí saem três regras:

RegraSem ela
o aviso pertence à propagação, e não ao recálculouma simples leitura disparava efeito de terceiros
o efeito alcançado por dois caminhos roda uma veza tela redesenhava duas vezes por mudança
a dedup é pelo objeto, e não por id()id() só é único entre objetos vivos
uma escrita dentro de um efeito abre a próxima ondaa fila cresceria enquanto é percorrida

Lote#

dataforge
action tres_escritas():
    itens.escrever([...])
    cupom.escrever(0.0)
    itens.escrever([...])

R.lote(tres_escritas)      // UMA notificacao

Sem ele, mudar três sinais que alimentam o mesmo derivado faz o efeito rodar três vezes — e as duas primeiras mostram um estado intermediário que nunca deveria aparecer na tela.

Se a ação falhar no meio, os avisos saem mesmo assim: a escrita já aconteceu, e engolir a notificação deixaria a tela mostrando um estado que não é mais o do programa.