Structured Concurrency
Binding a concurrent operation's lifetime to its parent's, so cancelling the parent explicitly propagates to every child it started.
Purpose
Structured concurrency means a concurrent operation’s children never outlive their parent — when the parent is cancelled or completes, every child operation is cancelled or awaited too, with nothing left running independently and unaccounted for.
Example
async function processAll(items, signal) {
const controller = new AbortController();
signal.addEventListener('abort', () => controller.abort()); // parent cancellation propagates
try {
await Promise.all(items.map((item) => processItem(item, controller.signal)));
} finally {
controller.abort(); // no child outlives this function, success or failure
}
}
Behavior notes
- Cancellation does not propagate automatically in JavaScript — it requires explicit wiring, most
often a child
AbortControllerwhose signal aborts when the parent’s does. Promise.allitself provides a related but distinct guarantee: it settles once all promises settle, but doesn’t cancel the others if one rejects — only explicitAbortControllerwiring does that.- The
finallyblock above ensures cleanup happens on every exit path (success, error, or external cancellation) — a common structured-concurrency idiom.
Common mistakes
- Assuming cancelling an outer operation automatically cancels whatever async work it started internally — without explicit signal propagation, “cancelled” children keep running to completion, wasting work and potentially mutating state the caller believed was abandoned.
- Creating child operations without ever wiring their cancellation to the parent at all, leaving no way to stop them once started.
Runtime notes
A coding discipline built on core AbortController/Promise behavior, applicable anywhere
JavaScript’s async model is used.