Skip to content

Disposable AbortController #1405

@bakkot

Description

@bakkot

What problem are you trying to solve?

Now that explicit resource management is shipping, it would be very useful if there were a way to get an AbortController which aborted when disposed. That would let you write something like

using controller = new AbortController.AutoAbort();
let pages = await Promise.all(urls.map(url => fetch(url, { signal: controller.signal }));
// automatically cancels outstanding requests if any request fails

without needing an explicit try/finally. See some further discussion here.

What solutions exist today?

You can use a try-finally:

let controller = new AbortController;
let pages;
try {
  pages = await Promise.all(urls.map(url => fetch(url, { signal: controller.signal }));
} finally {
  controller.abort();
}

or make a DisposableStack:

using stack = new DisposableStack();
const { signal } = stack.adopt(new AbortController(), (controller) => controller.abort());
let pages = await Promise.all(urls.map(url => fetch(url, { signal }));

but those are both pretty awkward.

How would you solve it?

I would add a new kind of AbortController which implements the disposable protocol and which aborts when disposed.

In principle this is doable with an option to the constructor, but that means the return type depends on the arguments to the constructor, which is generally considered awkward.

Another option is to just make all AbortControllers disposable in this way. @rbuckton has argued against this because he wants some way to mark an AbortController as "closed but not aborted" and remove all callbacks, and wants this to be the default disposing behavior. I'm fine with that I guess.

A third option is to have the AbortController be disposable and have an option to control whether disposing aborts or merely "closes" the AbortController as in the previous paragraph.

(Sorry for using the wrong issue template initially.)

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