Future[Asynchronous Programming Tool] in Flutter (and Dart)

Roopesh Tripathi
3 min readOct 4, 2024

--

Photo by Marija Zaric on Unsplash

In Flutter (and Dart), Future is a core part of the Dart programming language and is neither a framework nor a library. It is conceptually similar to Promises in JavaScript.

What is a Future?

A Future represents a potential value or error that will be available at some point in the future, after an asynchronous operation is completed. It handles tasks that might take time, such as fetching data from the internet, reading a file, or performing complex computations.

How it works:

  • Uncompleted Future: When a Future is first created, it is uncompleted.
  • Completed Future: Once the asynchronous task is finished, the Future is completed with either:
  • A value: If the task was successful.
  • An error: If something went wrong during the task.

Without async/await: Using then() and catchError()

You can work with Future directly using its built-in methods like then() to handle success and catchError() to handle errors.

Example using then() and catchError():

Future<String> fetchUserData() {
return Future.delayed(Duration(seconds: 2), () => "User data loaded");
}

void main() {
fetchUserData().then((data) {
print(data); // Output: User data loaded
}).catchError((error) {
print("Error: $error");
});
}

In this example:

  • then(): Runs when the Future completes successfully and provides the result (data).
  • catchError(): Runs if an error occurs during the execution of the Future.

This approach is perfectly valid but can become difficult to read when chaining multiple asynchronous operations, resulting in “callback hell.”

With async/await: More Readable Code

The async/await syntax simplifies the process of working with Future and makes the code look more sequential, even though it's asynchronous under the hood.

Example using async/await:

Future<String> fetchUserData() async {
await Future.delayed(Duration(seconds: 2)); // Simulate a delay
return "User data loaded";
}

void main() async {
String userData = await fetchUserData(); // Wait for the Future to complete
print(userData); // Output: User data loaded
}

With async/await:

Future<void> loadData() async {
try {
String userData = await fetchUserData();
print(userData);
String moreData = await fetchMoreData(); // Another async operation
print(moreData);
} catch (error) {
print("Error: $error");
}
}

void main() {
loadData();
}

Comparison with JavaScript’s Promises:

Just like Promises in JavaScript, a Future allows you to execute code asynchronously and handle the result when it's ready. You can use then() and catchError() methods for handling success and errors respectively, or use the async/await syntax to make the code more readable.

Basic Future Methods:

  1. then(): Used to register callbacks for when the Future completes successfully.
  2. catchError(): Used to handle errors if the Future completes with an error.
  3. await: Pauses the execution of code until the Future completes, without blocking the entire application.

Conclusion:

  • Future is a Dart core feature, not a framework or library.
  • It works like a Promise in JavaScript for handling asynchronous tasks.
  • It helps manage tasks that will be completed in the future, such as network requests or file I/O, making it essential for asynchronous programming in Flutter.
  • async/await is not mandatory but makes asynchronous code more readable and maintainable.
  • You can still use Future without it by relying on then() and catchError(), but async/await avoids deeply nested callbacks.
  • In most cases, async/await is preferred for cleaner and easier-to-understand code.

--

--

Roopesh Tripathi
Roopesh Tripathi

Written by Roopesh Tripathi

👋 Hello, I'm Roopesh Tripathi! 📱 Mobile Developer | iOS Enthusiast | Swift Advocate 💻 Passionate about crafting elegant and efficient mobile apps.

No responses yet