Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Computed still updating (and subscribed to input observables) while output not observed #162

Open
quixot1c opened this issue Apr 7, 2021 · 3 comments
Labels
question Further information is requested

Comments

@quixot1c
Copy link

quixot1c commented Apr 7, 2021

When trying the following code

const obs = observable(1);
const observer = () => { console.log("inside: " + obs()); return obs() };
const comp = computed(observer);
const unsub = subscribe(() => console.log(comp()));

obs(2);
unsub();
obs(3);
unsubscribe(observer);
obs(4);

we get the output

inside: 1
1
inside: 2
2
inside: 3

while I would kind of expect the logs from inside the computed to stop after the unsub(). But this is only the case when I call unsubscribe on the function that went into computed (which also puzzled me a bit).

Is it desirable that computeds still fire internally even when their output (data) is not subscribed to?

I think my use case with the pipe functionality that I am building would benefit greatly from automatic internal unsubscribe from a computeds observable inputs, because that would propagate up the chain, eventually allowing me to detect a whole chain has become unobserved at the beginning of the chain, which then allows me to stop the Websocket connection that produces the data for the chain.

@luwes luwes added bug Something isn't working question Further information is requested and removed bug Something isn't working labels Apr 10, 2021
@luwes
Copy link
Owner

luwes commented Apr 10, 2021

thanks for the feedback, I removed the bug label for now but what you explain does makes sense to me.
I'm not sure it's possible to change this behavior though without breaking things.

another call to comp() in the end would have to have an updated value of course but it could be more like a lazy evaluation then.

wonder what S.js and MobX does in this case? do you happen to know?

@quixot1c
Copy link
Author

I investigated a little further and it seems that the data() function that is returned from a call to computed() is different from the data() returned by observable(). The one from observable has ._observers but the one from computed does not. So it seems the data returned from computed does not keep track of who is observing it and executing the observers when changes occur to it. And so it also doesn't know when it isn't being observed and doesn't know when to internally unobserve the observables inside.

I'm not sure about S or MobX's workings I'm afraid.

@Freak613
Copy link

Freak613 commented May 11, 2021

Mobx has ref counting for computeds, disposing them when not in use.

Sjs use roots for this purpose, disposing all computations at once, but not until dispose is called. This results in zombie computations that will keep working until parent disposed or re-run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants