-
Couldn't load subscription status.
- Fork 318
Description
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 failswithout 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.)