Computed still updating (and subscribed to input observables) while output not observed · Issue #162 · luwes/sinuous · GitHub
Skip to content

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

Open

Description

@quixot1c

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.

Activity

  1. added
    bugSomething isn't working
    questionFurther information is requested
    and removed
    bugSomething isn't working
    on Apr 10, 2021
  2. luwes commented on Apr 10, 2021

    @luwes
    Owner

    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?

  3. quixot1c commented on Apr 10, 2021

    @quixot1c
    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.

  4. Freak613 commented on May 11, 2021

    @Freak613

    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.

  5. mindplay-dk commented on Mar 13, 2025

    @mindplay-dk
    Contributor

    Have you folks seen this?

    https://developer.chrome.com/blog/movebefore-api

    I wonder if reconciliation can now literally take the naive approach and just do this?

    function diff(parent, oldChildren, newChildren, endMarker) {
      let set = new Set();
      for (let i=newChildren.length; i--;) {
        set.add(newChildren[i]);
      }
      for (let i=oldChildren.length; i--;) {
        let oldChild = oldChildren[i];
        if (!set.has(oldChild)) {
          parent.removeChild(oldChild);
        }
      }
      for (let i=newChildren.length; i--;) {
        parent.moveBefore(newChildren[i], newChildren[i+1] || endMarker);
      }
      return newChildren;
    }

    I mean, moveBefore preserves state not only of iframes and CSS but presumably selection and focus, too, right?

    I wonder if making fewer moves still matters for the sake of performance, or if you can literally just "brute force" reorder now? 😏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions