So I'm trying to get a bit of a deeper understanding of signals more generally after having used them for a while.
I stumbled over this change of how computed signals get evaluated when they're included in effects which intuitively makes sense but I'm wondering how, on a high-level description, that is implemented.
So say I have a component like this:
export class AppComponent implements OnInit {
x = signal(1);
y = computed(() => {
console.log("Fired Computed", this.x())
return 2*this.x();
})
ngOnInit(): void {
interval(1000).subscribe(() => {
console.log("Fired Setting x to ", this.x()+1)
this.x.set(this.x() + 1)
})
}
This will never evaluate y() since its never used anywhere, so for y the computed evaluation is lazy.
But if you now add a constructor with an effect to that component
constructor() {
effect(() => {
console.log("Fired Effect")
console.log("Fired: ", this.y());
})
}
What I observe now is this:
Fired Setting x to 2
app.component.ts:19 Fired Computed 2
app.component.ts:28 Fired Effect // This here gets logged *before the effect itself ever reads computed*
app.component.ts:29 Fired: 4
app.component.ts:35 Fired Setting x to 3
app.component.ts:19 Fired Computed 3
app.component.ts:28 Fired Effect
app.component.ts:29 Fired: 6
So now computed eagerly gets evaluated before it even gets accessed in the effect.
Conceptually, how is that set up?
I'm already aware there's a global effect registry in Angular which can mark effects as dirty and eventually a tick runs regularly that executes all dirty effects.
But how do you slot into that to change the behavior of all signals inside it?