I thought this was one of the more interesting things I’ve written recently. It seems pretty simple from the small amount of code but it combines a couple things that I rarely use – Generator functions and Abort Controllers (outside of Fetch).

async function* sendInSeries(items, signal) {
    let cancelled = false;
    if (signal) {
        signal.addEventListener("abort", () => {
            cancelled = true;
        });
    }

    for (const item of items) {
        if (cancelled) break;
        yield await sendAPIRequest(item); // some async task
    }
}

This is a cancellable async generator function that can be used to run a series of async tasks such as API requests. If I have a list of 10 items, this can process each item by making an API call asynchronously and yeild the result for each request. If I provide an AbortController signal then I can cancel the batch at any time.

Usage is as follows:

const abortController = new AbortController(); 
const analyzer = sendInSeries(myItems, abortController.signal);

for await (const result of analyzer) {
    // Handle result for each item
}

/*
I can call abortController.abort() at any time to cancel the batch
*/