Skip to content
Chapter 7Lesson 5

Quiz - Async semantics

Quiz progress

0 / 0

Predict the output of this program.

setTimeout(() => console.log('A'), 0);
Promise.resolve().then(() => console.log('B'));
console.log('C');

C, B, A

C, A, BsetTimeout(..., 0) runs before any queued microtask because its delay has already elapsed.

A, B, C — scheduled callbacks fire before the rest of the synchronous script.

A dashboard renders three independent reads — the user, the org, and the recent invoices. The user read is critical; the other two are nice-to-have, and the page should render whatever succeeded. Which combinator fits?

Promise.allSettled — it never rejects and hands back per-item { status, value? , reason? }, so the caller decides per result what to render.

Promise.all — wrap everything in one await; if a non-critical read fails, catch it at the top and render anyway.

Promise.any — it succeeds as soon as one of the three reads fulfills, which covers the “render what you can” case.

A route handler runs:

const user = await getUser(userId);
const org = await getOrg(orgId);
const invoices = await listRecentInvoices(orgId);

Each call takes ~200ms; nothing reads the previous return value. What’s the senior rewrite?

const [user, org, invoices] = await Promise.all([
getUser(userId),
getOrg(orgId),
listRecentInvoices(orgId),
]);

Wrap the awaits in a for...of loop over [getUser, getOrg, listRecentInvoices] to keep them in order while reducing the syntax noise.

Leave it — sequential awaits are the safest default; rewriting to Promise.all opens the code to race conditions between the three reads.

A fetch whose signal was created with AbortSignal.timeout(5_000) rejects after the deadline elapses. Which catch block correctly distinguishes user-cancel from a deadline expiry?

catch (err) {
if (err instanceof Error && err.name === 'AbortError') return;
if (err instanceof Error && err.name === 'TimeoutError') {
notify('Request timed out');
return;
}
throw err;
}
catch (err) {
if (err instanceof DOMException) return; // covers abort and timeout
throw err;
}
catch (err) {
if (err instanceof Error && err.name === 'AbortError') return;
throw err;
}

You need to expose “the next inbound message on this socket” as a Promise. Which shape is the 2026 default?

const { promise, resolve, reject } = Promise.withResolvers<Message>();
socket.once('message', resolve);
socket.once('error', reject);
return promise;
let resolve!: (m: Message) => void;
let reject!: (e: Error) => void;
const promise = new Promise<Message>((res, rej) => {
resolve = res;
reject = rej;
});
socket.once('message', resolve);
socket.once('error', reject);
return promise;
return new Promise<Message>((resolve, reject) => {
Promise.race([
new Promise<Message>((r) => socket.once('message', r)),
new Promise<Message>((_, r) => socket.once('error', r)),
]).then(resolve, reject);
});

An admin tool calls await Promise.all(orderIds.map((id) => fetchOrder(id))) where orderIds.length can be 500 and fetchOrder is a database read. The page either times out or exhausts the connection pool. Which of these are correct fixes? Select all that apply.

Replace with a single batched query: db.select().from(orders).where(inArray(orders.id, orderIds)).

Use pMap(orderIds, fetchOrder, { concurrency: 8 }) to cap concurrency.

Rewrite as for (const id of orderIds) { results.push(await fetchOrder(id)); } — sequential is the safe default for large N.

Wrap the existing Promise.all in Promise.allSettled — failures will no longer crash the page.

True or false: code that appears before the first await inside an async function runs synchronously on the caller’s stack, and the function only returns a pending Promise once it actually hits the await.

True.

False — the entire body of an async function is deferred to a microtask the moment the function is called.

You want a single fetch to be cancellable from three independent sources: the user clicking Stop, a 30-second deadline, and a process-wide shutdown signal. What’s the canonical 2026 shape?

const signal = AbortSignal.any([
userController.signal,
AbortSignal.timeout(30_000),
shutdownSignal,
]);
await fetch(url, { signal });
await Promise.race([
fetch(url, { signal: userController.signal }),
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), 30_000)),
new Promise((_, reject) => shutdownSignal.addEventListener('abort', () => reject(new Error('shutdown')))),
]);
if (userController.signal.aborted || shutdownSignal.aborted) return;
await fetch(url, { signal: AbortSignal.timeout(30_000) });

Quiz complete

Score by topic