skip adding dependencies for destroyed effects

aa-coordination
Rich Harris 7 months ago
parent c2869f5617
commit 5f2abc8fb4

@ -529,6 +529,7 @@ function remove_reaction(signal, dependency) {
} }
} }
} }
// If the derived has no reactions, then we can disconnect it from the graph, // If the derived has no reactions, then we can disconnect it from the graph,
// allowing it to either reconnect in the future, or be GC'd by the VM. // allowing it to either reconnect in the future, or be GC'd by the VM.
if ( if (
@ -965,35 +966,41 @@ export function get(signal) {
e.state_unsafe_local_read(); e.state_unsafe_local_read();
} }
var deps = active_reaction.deps; // if we're in an async derived, the parent effect could have
// already been destroyed
if ((active_reaction.f & REACTION_IS_UPDATING) !== 0) { var destroyed = active_effect !== null && (active_effect.f & DESTROYED) !== 0;
// we're in the effect init/update cycle
if (signal.rv < read_version) { if (!destroyed) {
signal.rv = read_version; var deps = active_reaction.deps;
// If the signal is accessing the same dependencies in the same if ((active_reaction.f & REACTION_IS_UPDATING) !== 0) {
// order as it did last time, increment `skipped_deps` // we're in the effect init/update cycle
// rather than updating `new_deps`, which creates GC cost if (signal.rv < read_version) {
if (new_deps === null && deps !== null && deps[skipped_deps] === signal) { signal.rv = read_version;
skipped_deps++;
} else if (new_deps === null) { // If the signal is accessing the same dependencies in the same
new_deps = [signal]; // order as it did last time, increment `skipped_deps`
} else { // rather than updating `new_deps`, which creates GC cost
new_deps.push(signal); if (new_deps === null && deps !== null && deps[skipped_deps] === signal) {
skipped_deps++;
} else if (new_deps === null) {
new_deps = [signal];
} else {
new_deps.push(signal);
}
} }
} } else {
} else { // we're adding a dependency outside the init/update cycle
// we're adding a dependency outside the init/update cycle // (i.e. after an `await`)
// (i.e. after an `await`) (active_reaction.deps ??= []).push(signal);
(active_reaction.deps ??= []).push(signal);
var reactions = signal.reactions; var reactions = signal.reactions;
if (reactions === null) { if (reactions === null) {
signal.reactions = [active_reaction]; signal.reactions = [active_reaction];
} else if (!reactions.includes(active_reaction)) { } else if (!reactions.includes(active_reaction)) {
reactions.push(active_reaction); reactions.push(active_reaction);
}
} }
} }
} else if ( } else if (

Loading…
Cancel
Save