How does async/await work in Dart?
Short Answer
`async` marks a function as returning a Future and lets you use `await` inside it; `await` pauses execution of that function (without blocking the thread) until the awaited Future completes.
Dart is single-threaded for your app code (it uses an event loop, not OS threads, for concurrency). When you `await` a Future, Dart doesn't block the thread — it suspends the current async function and lets the event loop keep processing other work (like UI rendering) until the awaited value is ready, then resumes exactly where it left off.
An `async` function always returns a Future, even if you don't explicitly wrap the return value — `Future<int> getCount() async { return 5; }` returns a `Future<int>` that completes with 5. Errors thrown inside an async function become a failed Future, which you catch with try/catch around the `await`, same as synchronous code.
Code Example
Future<void> loadProfile() async {
try {
final user = await fetchUser();
print(user);
} catch (e) {
print('Failed to load: $e');
}
}Common Mistakes
- ×Marking a function `async` but forgetting to `await` a Future inside it — the function returns before the work finishes.
- ×Thinking `await` blocks the UI thread — it doesn't; it yields control back to the event loop.
Related Questions
What is the difference between Future and Stream in Dart?
A Future represents a single asynchronous value that completes once; a Stream represents a sequence of asynchronous values delivered over time, and can emit zero, one, or many events.
What is null safety in Dart?
Sound null safety means the compiler distinguishes nullable (`String?`) from non-nullable (`String`) types and guarantees, at compile time, that a non-nullable variable can never hold null.