async/await: Write Concurrent Code That Reads Synchronously
async/await lets you write asynchronous code that reads like a synchronous story, eliminating callback hell. It's ideal for network requests or file I/O. The footgun is thinking await blocks a thread; it only suspends the current task.
Why it exists
Before async/await, Swift used completion handlers for asynchronous tasks. Chaining operations, like a network call followed by data parsing, led to nested closures known as "callback hell" or the "pyramid of doom." This code was difficult to read, reason about, and handle errors in consistently.
The mental model
Think of an async function as one that can pause itself. The async keyword marks a function as pausable. The await keyword is where you actually press pause. When you await a task, your function yields the thread back to the system, saying "I'm waiting for this to finish; feel free to do other work." Once the awaited task completes, your function resumes right where it left off with the result.
How it works
The Swift compiler and runtime work together to manage structured concurrency. An async function is broken into parts at each potential suspension point (await). When a function is suspended, its state is saved, and the thread is returned to a cooperative pool to run other work. This prevents threads from being blocked while waiting for I/O. To run an async function from a synchronous context, you must create a new concurrent context using a Task, like Task { await myFunction() }.
When to use it
Use async/await for nearly all new asynchronous code in Swift. It's ideal for I/O-bound operations like network requests, file access, or database queries. It keeps the UI responsive by easily moving work off the main thread without the complexity of manual thread management with Grand Central Dispatch (GCD).
When not to use it
For CPU-bound, highly parallelizable tasks, lower-level APIs like GCD's DispatchQueue.concurrentPerform might still provide more fine-grained control and performance. Also, when working with legacy codebases that heavily use completion handlers, you'll need to write bridging code (e.g., using withCheckedContinuation) rather than replacing everything at once.
One canonical example
Fetching a user and then their avatar. Before, this required nested callbacks. With async/await, the code is linear:
func fetchUserAndAvatar(userID: String) async throws -> (User, UIImage) {
let user = try await api.fetchUser(id: userID)
let avatar = try await imageLoader.fetchImage(url: user.avatarURL)
return (user, avatar)
}This looks synchronous, but await allows the thread to do other work during the network calls, and try/catch handles errors from both operations cleanly.
Interview question
What is the fundamental behavior of the "await" keyword within an "async" function in Swift?
- a.It halts the execution of the current thread until the awaited operation returns a result.
- b.It ensures that the subsequent code runs on a dedicated background thread to prevent UI blocking.
- c.It marks the function as capable of being executed concurrently with other operations.
- d.It suspends the current task, allowing the system to use the thread for other pending work.Correct
Why? this is the answer
The "await" keyword suspends the current task, returning the thread to the system to perform other work until the awaited operation completes. It does not block the thread, which is a common misconception.
Just read this? Test yourself on what you have been reading.
Read the original → docs.swift.org
- #swift
- #concurrency
- #async/await
- #ios
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.
We are hiring for this. Open roles that interview on swift — each one lists the topics its interview covers.
See open roles