Right now I have code that is basically:
var loadingIndicator = /* Reference to UI component */,
output = /* Reference to UI component */,
abortController;
function onThingRequested(thing) {
abortController?.abort();
requestThing(thing);
}
async function requestThing(thing) {
abortController = new AbortController();
output.innerText = '';
loadingIndicator.show();
try {
console.log(`STARTING ${thing}`);
// For the sake of brevity of the example, assume `thing` is safe to put here.
var thingRes = await fetch(`/example?thing=${thing}`, { signal: abortController.signal });
output.innerText = await thingRes.text();
} catch (err) {
console.log(`ERRORED ${thing}`);
output.innerText = err;
} finally {
console.log(`FINALLY'D ${thing}`);
loadingIndicator.hide();
}
}
If I trigger onThingRequested('thing1')
and then, before it loads, trigger onThingRequested('thing2')
, the output is, of course…
STARTED thing1
STARTED thing2
ERRORED thing1
FINALLY'D thing1
FINALLY'D thing2
…because requestThing
triggers the new fetch immediately, while the abort happens asynchronously. Is there any elegant way to wait for the prior fetch to finish aborting before proceeding? Besides, of course, the hacky-feeling workaround of…
function onThingRequested(thing) {
abortController?.abort();
setTimeout(() => requestThing(thing), 1);
}