Skip to content
tezvyn:

async/await: Write Concurrent Code That Reads Synchronously

Source: docs.swift.orgHardHow cards are made

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?

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

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