Asynchronous Programming in Flutter
Learn about asynchronous programming in Flutter using Futures and async/await to handle time-consuming tasks and network requests efficiently.
Learn about asynchronous programming in Flutter with async/await, Future.then(), and Future.catchError().
Discover how to manage long-running tasks, handle errors gracefully, and maintain a responsive user experience in your Flutter app.
Usage of async and await in Flutter
By using async/await, you ensure that your Flutter app remains responsive during these time-consuming tasks.
The async keyword is used to declare a function as asynchronous, allowing the function to use await. When you use async with a function, you can use await inside that function, indicating that the function may contain asynchronous operations.
Future fetchData() async {
// Simulating a network request that takes 2 seconds
await Future.delayed(Duration(seconds: 2));
return 42;
}
void main() async {
int data = await fetchData();
print("Data fetched: $data"); // Output: Data fetched: 42
}
In this example, fetchData() is an asynchronous function marked with async. Inside the function, we use await Future.delayed(Duration(seconds: 2)) to simulate a network request that takes 2 seconds.
The await keyword pauses the function's execution until the Future returned by Future.delayed() completes.
Usage of Future.then() and Future.catchError()
Flutter provides another way to handle asynchronous operations using Future.then() and Future.catchError() methods.
After initiating a Future, you can chain .then() to handle the result when the Future completes successfully, and .catchError() to handle any errors that occur during the Future's execution.
Here's an example using Future.then() and Future.catchError():
// Simulating fetching user data from a local database
Future<Map<String, dynamic>> fetchUserData() async {
await Future.delayed(const Duration(seconds: 2));
return {'name': 'John Doe', 'age': 30};
}
// Simulating updating the user data
Future<void> updateUserData(Map<String, dynamic> userData) async {
await Future.delayed(const Duration(seconds: 2));
userData['age'] = 31;
}
// Simulating saving user data to a remote server
Future<void> saveUserDataToServer(Map<String, dynamic> userData) async {
await Future.delayed(const Duration(seconds: 2));
// Uncomment the line below to simulate an error
// throw Exception("Failed to save data to server.");
}
// Call this fun inside build..
void runThis() {
late Map<String, dynamic> userData; // Declare 'userData' outside the chain
fetchUserData().then((data) {
// The fetched user data is assigned to the 'userData' variable
userData = data;
print("User Data Fetched: $userData");
// Return the updated user data to continue the chain
return updateUserData(userData); // Updating user data
}).then((_) {
// 'userData' is still accessible here because it was declared outside the chain
print("User Data Updated: $userData");
// Call saveUserDataToServer() and return 'null' to continue the chain
return saveUserDataToServer(userData); // Saving user data to the server
}).then((_) {
// 'userData' is still accessible here
print("User Data Saved to Server");
// This is the final 'then' block, and the chain ends here.
// You can perform any follow-up operations here.
}).catchError((error) {
// Catch any errors that occur during any step in the chain.
print("Error occurred: $error");
// Handle the error as needed
});
}
If any error occurs during any of these operations, the Future.catchError() will catch the error, and we can handle it gracefully.
..
Comments
Post a Comment