I have a subscription management in my ko model, which saves any subscription by intercepting them and saving reference to them.
I then dispose() them, but I need to understand sometimes if a sub is already disposed. Is the member Gb, a boolean of the subscription object, an active-inactive flag? I see that sometimes when I dispose a subscription its Gb becomes false, sometimes not. Do I have to interpret this as a dispose fail?
And once I dispose a subscription, the subscription object, is ready to be garbage collected?
EDIT: I just need to understand if a subscription is already disposed, as said in the title. I obtain the subscription in the only way I know, saving a reference to it when declared:
var mySub = myObservable.subscribe(function(){/*do something*/});
Some time after I need a way to determine if mySub is already disposed.
function isDisposed(mySubscription) {
// if is disposed return true else return false
}
I need to perform some logic based on this, not only dispose it if it is not disposed already (or I could simply call again the dispose method). Is it possible to determine subsbcription disposal status?
About manual subscriptions
Knockout source is compiled with Google Closure Compiler so only properties and methods explicetly exported in source appear in compiled library code.
With that said a subscription has a "private" property
isDisposed
, but it is not exported. Thus the only API exported for subscription isdispose
.Glimps of source code - ko.subscription (knockout-3.1.0.debug):
About memory leaks and computeds
1) Just an interesting fact about computeds - consider the following computed
In this example
myComputed
has 2 dependecies. But if we were to assingfalse
tomyObservable1
myComputed
would reevaluate and after reevalution it would only have 1 dependency and subscription tomyObservable2
would be disposed.Why it is disposed:
The explanation lies in how computed is evaluated - it registers dependencies the following way - if any observable is read (meaning code like
myObservable1()
) during evaluation - computed recieves a callback with this observable, checks its id and stores it in a new dependency array. Once evaluation is complete - old dependency array is disposed. In our example whenmyObservable1
is set to falsemyObservable2
is never read - since we never enter if block. So it is not a new dependecy and old dependency is disposed.2) Another interesting fact. Consider snippet:
The computed is not collected by garbage collector because infact the reference to it exists inside it's dependency.
Glimps of source code - ko.computed (knockout-3.1.0.debug):
Reference to dependentObservable is preserved because reference to evaluatePossiblyAsync is preserved (Closures, JS and all that Jazz).
Whoa, that is all I had to say. Hope some thought come to mind.