Async and Await in Dart
In this lesson, you will learn about async and await in Dart.
These keywords make working with Future objects easier, cleaner, and more readable.
Async and await are built on top of Futures, but they allow you to write asynchronous code that looks like synchronous code.
Why Async & Await Are Important
Without async and await, handling futures using then() can become complex
and difficult to read when logic grows.
Async and await solve this problem by simplifying asynchronous workflows.
Basic Async Function
An async function always returns a Future.
Future fetchMessage() async {
return "Hello from async function";
}
Using Await
The await keyword pauses execution until the future completes.
void main() async {
String message = await fetchMessage();
print(message);
}
Async with Delayed Operations
Let’s simulate a real-world API call using delay.
Future fetchUserAge() async {
await Future.delayed(Duration(seconds: 2));
return 28;
}
Consuming the Async Function
void main() async {
print("Fetching age...");
int age = await fetchUserAge();
print("User Age: $age");
}
Execution Flow Explanation
- The program starts immediately
- Execution pauses at
await - Resumes after the future completes
Async Function with Multiple Awaits
Async functions can await multiple futures in sequence.
Future fetchUserData() async {
await Future.delayed(Duration(seconds: 1));
String name = "Alex";
await Future.delayed(Duration(seconds: 1));
String city = "San Jose";
return "$name from $city";
}
Using the Function
void main() async {
String user = await fetchUserData();
print(user);
}
Handling Errors with try-catch
Errors inside async functions are handled using try-catch.
Future divide(int a, int b) async {
if (b == 0) {
throw Exception("Division by zero");
}
return a ~/ b;
}
Error Handling Example
void main() async {
try {
int result = await divide(10, 0);
print(result);
} catch (e) {
print("Error: $e");
}
}
Async vs then()
Async/await improves:
- Readability
- Error handling
- Maintainability
Async code looks cleaner and closer to natural logic flow.
Parallel Execution with Future.wait()
You can still combine async/await with Future.wait().
Future loadDashboard() async {
var results = await Future.wait([
Future.delayed(Duration(seconds: 2), () => "Profile Loaded"),
Future.delayed(Duration(seconds: 1), () => "Settings Loaded"),
Future.delayed(Duration(seconds: 3), () => "Messages Loaded"),
]);
results.forEach(print);
}
Real-World Use Cases
- API calls
- Database queries
- File reading and writing
- User authentication
Common Mistakes
- Using
awaitoutside async function - Forgetting error handling
- Blocking logic inside async code
📝 Practice Exercises
Exercise 1
Create an async function that returns a username after a delay.
Exercise 2
Handle an error using try-catch.
Exercise 3
Use multiple await statements in a function.
✅ Practice Answers
Future getUsername() async {
await Future.delayed(Duration(seconds: 2));
return "dataplexa_user";
}
void main() async {
try {
String user = await getUsername();
print(user);
} catch (e) {
print(e);
}
}
What’s Next?
In the next lesson, you will learn about Streams in Dart, which handle multiple asynchronous values over time.