Skip to content

Add a method like .addTeardown to AbortSignal #1289

Open
@Jamesernator

Description

@Jamesernator

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    addition/proposalNew features or enhancementsneeds implementer interestMoving the issue forward requires implementers to express interesttopic: abortingAbortController and AbortSignal

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions