Skip to content
tezvyn:

How does Swift async/await improve on completion handlers?

Source: docs.swift.orgHardHow cards are made

Tests structured concurrency mastery over callback control flow. A strong answer covers inversion of control, suspension points as yield locations, and Tasks as parent-child units.

What's really being asked

Whether you understand the semantic shift from ad-hoc callbacks to structured concurrency. Interviewers want to see that you know async/await is not just cleaner syntax but a runtime contract involving cooperative scheduling, suspension, and task trees.

The full answer

Four things in order. First, completion handlers invert control and force manual state management across scattered callbacks, while async/await restores sequential top-to-bottom flow and makes error handling uniform via throws. Second, a suspension point is the exact spot marked by await where the current task voluntarily yields its thread back to the runtime without blocking the underlying thread, allowing other work to proceed while the async operation completes. Third, a Task is the fundamental unit of structured concurrency in Swift; it creates a concrete scope in which async work runs, enabling parent-child relationships so that cancelling a parent automatically cancels its children and awaiting a parent implicitly awaits all descendants. Fourth, structured concurrency guarantees that work started inside a scope cannot outlive that scope, preventing the orphaned callbacks and memory leaks common with completion handlers.

The mistakes people make

Calling async/await mere syntactic sugar over closures misses the runtime and thread-model differences. Confusing a Task with a DispatchQueue or an OS thread shows misunderstanding of Swift's cooperative thread pool. Saying await blocks the thread is a critical error; suspension frees the thread. Forgetting that Task.init creates an unstructured task while TaskGroup and async let create structured parent-child trees is another frequent gap.

What usually comes next

How does cancellation propagate through a task tree and how do you check for it inside an async function? When would you use an unstructured Task versus a TaskGroup? How does the runtime decide which thread to use after a suspension point resumes? What is the difference between a detached task and a child task regarding priority inheritance and cancellation?

A concrete example

Imagine fetching a user profile and then their avatar. With completion handlers, you nest two data tasks and manually manage a cancellation flag or operation queue. With async/await, you write let profile = try await fetchUser followed by let avatar = try await fetchAvatar with profile.id. Each await is a suspension point. If both calls run inside a single Task launched from a view model, cancelling that Task automatically propagates cancellation to both network requests because they are part of the same structured scope.

Interview question

In Swift structured concurrency, what distinguishes a Task started with Task.init from a child task created via async let?

  • a.They differ only in syntax; both produce the same underlying closure-based execution model
  • b.Task.init inherits the parent's priority and cancellation, while async let tasks are detached and independent
  • c.Task.init runs on a dedicated OS thread, while async let tasks share the cooperative thread pool
  • d.Task.init creates an unstructured task without parent-child cancellation propagation, while async let creates a structured child taskCorrect
Why?

Task.init creates an unstructured task outside the parent-child tree, whereas async let creates a structured child task bound to its parent's scope and cancellation. Claiming they differ only in syntax repeats the common misconception that async/await is mere syntactic sugar, ignoring the runtime contract of structured concurrency.

Just read this? Test yourself on what you have been reading.

Read the original → docs.swift.org

Put your scrolling time to good use

Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on swift — each one lists the topics its interview covers.

See open roles