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

Add a method like .addTeardown to AbortSignal #1289

Open
Jamesernator opened this issue May 18, 2024 · 0 comments
Open

Add a method like .addTeardown to AbortSignal #1289

Jamesernator opened this issue May 18, 2024 · 0 comments
Labels
addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest topic: aborting AbortController and AbortSignal

Comments

@Jamesernator
Copy link

Jamesernator commented May 18, 2024

What problem are you trying to solve?

(I did originally suggest this on the Observable proposal but it was suggested I propose this here instead.)

AbortSignal teardown is still fairly hazardous when relying on .addEventListener as the event may have already fired so it's very easy to have cleanup steps that don't occur when they should, the observable proposal adds a .addTeardown method that calls the given teardown steps immediately if the associated signal is already aborted else adds a listener.

Functionally there's not really any significant reason this method should be exclusive to Observables as the same patterns that have problems can occur when authoring code than involves Promises and/or callbacks.

What solutions exist today?

The alternative is writing a wrapper in userland, however in practice developers tend to forget the synchronously cancelled case which is why the Observable proposal even has the method.

How would you solve it?

I'd like to suggest that the method proposed as part of Observable is added to AbortSignal proper so that it can be used for all uses not just Observable.

As an example of usage:

function delay(time, { signal }={}) {
    return new Promise((resolve) => {
        const timeout = setTimeout(resolve, time);
        signal?.addTeardown(() => clearTimeout(timeout));
    });
}

// Already aborted
const p = delay(1000, { signal: AbortSignal.abort() });

This basically mirrors the comparable usage in Observable:

function interval(time) {
    return new Observable(subscriber => {
        const interval = setInterval(() => subscriber.next(), time);
        // If we added the method to AbortSignal, then this could just be
        // subscriber.signal.addTeardown(() => clearInterval(interval)) instead
        subscriber.addTeardown(() => clearInterval(interval));
    });
}

// Cancels immediately
interval(1000).subscribe({ ... }, { signal: AbortSignal.abort() });

Anything else?

No response

@Jamesernator Jamesernator added addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest labels May 18, 2024
@annevk annevk added the topic: aborting AbortController and AbortSignal label May 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest topic: aborting AbortController and AbortSignal
Development

No branches or pull requests

2 participants