pureComputed disposal with disposeWhenNoSubscribers in Knockout 3.5.0
0 reputation · 15 Apr 2025, 07:43 UTC
0 reputation · 15 Apr 2025, 07:43 UTC
The goal is to determine whether setting the disposeWhenNoSubscribers flag on a pureComputed observable in Knockout 3.5.0 triggers immediate disposal of its internal subscriptions once all external subscribers are removed, or whether disposal is deferred and limited to dependency cleanup. The pureComputed constructor, introduced in 3.5.0, automatically manages subscription lifecycle, but the interaction with disposeWhenNoSubscribers is not documented. Legacy computed observables created without the pure flag do not support this flag without code refactoring, creating a compatibility boundary for existing view models. Developers upgrading to 3.5.0 may encounter ambiguous cleanup behavior when both flags are present.
disposeWhenNoSubscribers cause a pureComputed to dispose its internal subscriptions immediately after the last external subscriber is removed?pureComputed?32275 reputation · 15 Apr 2025, 16:39 UTC
Yes — with disposeWhenNoSubscribers: true set, the disposal path fires when the last external subscriber is removed, and it is stronger than the normal pureComputed sleep behavior. But stacking that flag on a pureComputed is redundant at best and harmful at worst, because pureComputed already cleans up its dependency subscriptions on its own.
Confirmed behavior of pureComputed (3.5.0): a pureComputed automatically enters a sleeping state when it has no subscribers. While sleeping it unsubscribes from all dependencies, releases them, and stops evaluating. When read again (or subscribed to), it wakes, re-evaluates, and re-subscribes. This is the entire point of the pure flag — the cleanup you are asking about is built in.
What disposeWhenNoSubscribers adds: this option belongs to the general computed machinery. When the subscriber count drops to zero, it invokes the computed's dispose logic: dependency subscriptions are removed and the observable is marked disposed. The likely consequence — and this is the part worth verifying against your exact 3.5.x patch — is that a disposed computed does not reliably resume the way a sleeping pureComputed does. So instead of temporary sleep you can get permanent teardown: later reads return a stale value or silently stop updating rather than re-evaluating.
No. A dependent computed that subscribes to your pureComputed simply loses that subscription when the target is disposed. The dependent itself is not disposed, is not notified of the disposal, and keeps its last computed value. It will only change again if its other dependencies change — updates flowing through the disposed observable just stop arriving. This is a common source of "zombie UI": bindings still reference the disposed computed, so nothing errors, but nothing updates either.
None expected. Knockout's subscription and disposal logic is plain JavaScript with no browser-specific code paths, so Chromium, Firefox, and Safari should behave identically. If you see a difference, suspect timing in your own teardown code, not Knockout.
var source = ko.observable(1);
var pc = ko.pureComputed(function () { return source() * 2; });
var sub = pc.subscribe(function () {});
sub.dispose(); // last subscriber gone
// Sleeping pureComputed: dependencies released, but...
console.log(pc()); // ...reading it wakes it and re-evaluates
Repeat with ko.pureComputed({ read: fn, disposeWhenNoSubscribers: true }) and check whether the read after unsubscribe re-evaluates or stays inert — that distinguishes sleep from permanent disposal in your exact version. Then add a dependent computed over pc, trigger disposal, and confirm the dependent keeps working off its other dependencies.
pureComputed alone when you want automatic lifecycle management.ko.computed with disposeWhenNoSubscribers (or explicit .dispose()) when you want deterministic teardown.Caveat: the exact ordering of sleep vs. dispose internals is version-sensitive across 3.5.x patches, so run the verification snippet above against the build you actually ship.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.