Dart Async & Await
Handle asynchronous operations with ease
⏰ What is Async & Await?
Async and await help you write asynchronous code that looks like synchronous code. They make it easy to handle operations that take time, like network requests or file operations.
Future<String> fetchData() async {
await Future.delayed(Duration(seconds: 2));
return 'Data loaded!';
}
void main() async {
print('Loading...');
String result = await fetchData();
print(result);
}
Output:
Loading...
(2 seconds later)
Data loaded!
Async Programming Concepts
Async Functions
Functions that return Future objects
Future<String> getData() async {
return 'Hello';
}
Await Keyword
Wait for async operations to complete
String result = await getData();
print(result);
Future Objects
Represent values available in the future
Future<int> calculation =
Future.value(42);
Error Handling
Handle async errors with try-catch
try {
await riskyOperation();
} catch (e) {
print('Error: $e');
}
🔹 Basic Async Function
Create and use async functions:
// Simple async function
Future<String> greetUser(String name) async {
// Simulate some delay (like network request)
await Future.delayed(Duration(seconds: 1));
return 'Hello, $name!';
}
// Function that performs multiple async operations
Future<void> processUser(String name) async {
print('Processing user: $name');
// Wait for greeting
String greeting = await greetUser(name);
print(greeting);
// Simulate another async operation
await Future.delayed(Duration(milliseconds: 500));
print('User $name processed successfully!');
}
void main() async {
print('Starting...');
await processUser('Alice');
await processUser('Bob');
print('All done!');
}
Output:
Starting...
Processing user: Alice
Hello, Alice!
User Alice processed successfully!
Processing user: Bob
Hello, Bob!
User Bob processed successfully!
All done!
🔹 Parallel Async Operations
Run multiple async operations simultaneously:
Future<String> fetchUserData(String userId) async {
await Future.delayed(Duration(seconds: 1));
return 'User data for $userId';
}
Future<String> fetchUserPosts(String userId) async {
await Future.delayed(Duration(seconds: 2));
return 'Posts for $userId';
}
Future<String> fetchUserFriends(String userId) async {
await Future.delayed(Duration(seconds: 1));
return 'Friends for $userId';
}
void main() async {
String userId = 'user123';
print('Sequential execution:');
var start = DateTime.now();
// Sequential - takes about 4 seconds total
String userData = await fetchUserData(userId);
String userPosts = await fetchUserPosts(userId);
String userFriends = await fetchUserFriends(userId);
var sequential = DateTime.now().difference(start);
print('Sequential took: ${sequential.inMilliseconds}ms');
print('\nParallel execution:');
start = DateTime.now();
// Parallel - takes about 2 seconds (longest operation)
List<String> results = await Future.wait([
fetchUserData(userId),
fetchUserPosts(userId),
fetchUserFriends(userId),
]);
var parallel = DateTime.now().difference(start);
print('Parallel took: ${parallel.inMilliseconds}ms');
print('Results: $results');
}
Output:
Sequential execution:
Sequential took: ~4000ms
Parallel execution:
Parallel took: ~2000ms
Results: [User data for user123, Posts for user123, Friends for user123]
🔹 Error Handling in Async Code
Handle errors in asynchronous operations:
Future<String> fetchDataFromServer(String endpoint) async {
await Future.delayed(Duration(seconds: 1));
// Simulate different scenarios
if (endpoint == 'error') {
throw Exception('Server error occurred');
} else if (endpoint == 'timeout') {
throw TimeoutException('Request timed out', Duration(seconds: 5));
}
return 'Data from $endpoint';
}
Future<void> handleDataFetching() async {
List<String> endpoints = ['users', 'error', 'posts', 'timeout'];
for (String endpoint in endpoints) {
try {
print('Fetching from $endpoint...');
String data = await fetchDataFromServer(endpoint);
print('Success: $data');
} on TimeoutException catch (e) {
print('Timeout error: ${e.message}');
} catch (e) {
print('General error: $e');
} finally {
print('Finished processing $endpoint\n');
}
}
}
void main() async {
await handleDataFetching();
print('All requests completed!');
}
Output:
Fetching from users...
Success: Data from users
Finished processing users
Fetching from error...
General error: Exception: Server error occurred
Finished processing error
Fetching from posts...
Success: Data from posts
Finished processing posts
Fetching from timeout...
Timeout error: Request timed out
Finished processing timeout
All requests completed!
🔹 Async with Real-World Example
A practical example simulating a login process:
class AuthService {
Future<bool> validateCredentials(String username, String password) async {
print('Validating credentials...');
await Future.delayed(Duration(seconds: 1));
// Simple validation
return username == 'admin' && password == 'password123';
}
Future<String> fetchUserProfile(String username) async {
print('Fetching user profile...');
await Future.delayed(Duration(milliseconds: 800));
return 'Profile data for $username';
}
Future<List<String>> fetchUserPermissions(String username) async {
print('Fetching permissions...');
await Future.delayed(Duration(milliseconds: 600));
return ['read', 'write', 'admin'];
}
}
Future<void> loginUser(String username, String password) async {
var auth = AuthService();
try {
print('Starting login process for $username...');
// Step 1: Validate credentials
bool isValid = await auth.validateCredentials(username, password);
if (!isValid) {
print('Login failed: Invalid credentials');
return;
}
print('Credentials valid! Loading user data...');
// Step 2: Fetch user data in parallel
var results = await Future.wait([
auth.fetchUserProfile(username),
auth.fetchUserPermissions(username),
]);
String profile = results[0];
List<String> permissions = results[1] as List<String>;
print('Login successful!');
print('Profile: $profile');
print('Permissions: $permissions');
} catch (e) {
print('Login error: $e');
}
}
void main() async {
await loginUser('admin', 'password123');
print('---');
await loginUser('user', 'wrongpass');
}
Output:
Starting login process for admin...
Validating credentials...
Credentials valid! Loading user data...
Fetching user profile...
Fetching permissions...
Login successful!
Profile: Profile data for admin
Permissions: [read, write, admin]
---
Starting login process for user...
Validating credentials...
Login failed: Invalid credentials