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

Allow effect code to end the effect? #395

Open
pjeby opened this issue Jul 30, 2023 · 0 comments
Open

Allow effect code to end the effect? #395

pjeby opened this issue Jul 30, 2023 · 0 comments

Comments

@pjeby
Copy link

pjeby commented Jul 30, 2023

Currently, effects can only be ended from the "outside" - i.e., the caller creating the effect. But there are times when it's advantageous to allow an effect to cancel itself, since it knows when it is "done". (In particular, one can have effects decide when to end based on a shared signal, which is the use case I'm working on right now.)

In principle, you can share the dispose callback from the enclosing scope, and perhaps even make a helper function to simplify that process. But since the effect callback is synchronously invoked, this creates an edge case where you can't dispose the effect before the effect() call returns. Basically, you currently need a helper like this:

function disposableEffect(fn: (dispose: () => void) => void | (() => void)) {
    let dispose = function () {
        // wait for the effect() call to return
       Promise.resolve().then(() => dispose());
    }
    return dispose = effect(function(){
        return fn.call(this, dispose);
    });
}

This seems like it would be greatly simplified by making what is now _dispose into a public method, so that effect callbacks can just call this.dispose(), or even just return a special value to indicate that they wish to be disposed of.

(Note: while you can certainly stop an effect from having dependencies eventually, you can't actually get it to release without first receiving another callback, and if the reason you're trying to end the effect is because there aren't going to be any more callbacks, simply dropping all dependencies doesn't work to dispose of the reference cycle between the effect and its final dependencies.)

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

No branches or pull requests

1 participant