Skip to content

Instantly share code, notes, and snippets.

@jakearchibald
Last active February 16, 2024 10:45
Show Gist options
  • Star 26 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jakearchibald/8bc2360a6d3f6240d1bad2de375fa92a to your computer and use it in GitHub Desktop.
Save jakearchibald/8bc2360a6d3f6240d1bad2de375fa92a to your computer and use it in GitHub Desktop.
function preventUnhandledRejections(...promises) {
for (const promise of promises) promise.catch(() => {});
}
async function showChapters(chapterURLs, { signal: outerSignal }) {
outerSignal?.throwIfAborted();
const controller = new AbortController();
outerSignal?.addEventListener('abort', () => controller.abort());
const chapterPromises = chapterURLs.map(async (url) => {
const response = await fetch(url, { signal: controller.signal });
let data;
try {
data = await response.json();
} catch (err) {
throw Error(`Failed to parse ${url} as JSON: ${response.statusCode} ${response.statusText}`);
}
if (data.error) throw Error(data.error);
return data;
});
// Avoid unhandled rejections leaking out of this function.
// The subsequent `for await` handles all the relevant promises.
preventUnhandledRejections(...chapterPromises);
try {
for await (const chapterData of chapterPromises) {
appendChapter(chapterData);
}
} finally {
// Abort any remaining fetches
controller.abort();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment