Learning Dard - Asynchronous Programming in Dart with Futures, Async, and Await

Introduction to Dart

If you’re familiar with languages like C, Java, JavaScript, or C++, getting acquainted with Dart won’t be a daunting task. However, for those new to these languages, grasping Dart might take a little longer.

Variables in Dart

Variables in Dart can be either typed or dynamic. Here’s a simple example:

var name = 'Bob';

In this case, the variable name is of type String due to the assigned value.

Asynchronous Programming in Dart with Futures, Async, and Await

In software development, we often encounter situations where we need to wait for processes to complete before proceeding. This is where asynchronous programming comes into play. Dart offers powerful asynchronous capabilities using Future, async, and await keywords.

Futures in Dart

Future instances in Dart represent asynchronous computations. They can either be completed or uncompleted, providing a mechanism for handling asynchronous operations efficiently.

  • Uncompleted: This is the default state when a Future is created or when an asynchronous operation is in progress.
  • Completed: A Future transitions to the completed state when the asynchronous operation is finished.

A Future can also have a predefined return type, such as Future<String> to indicate that it will return a String when completed.

Here’s an example of a function returning a Future<String>:

Future<String> getStringFromAPI() async {
  return Future.delayed(Duration(seconds: 4), () => 'Large Latte');
}

In this example, the Future is expected to return a String when completed.

Working with Futures: Async and Await

To work with asynchronous functions effectively, Dart provides the async and await keywords.

  • async: This keyword is necessary before the function body to use await. Only async functions can use await.
  • await: This keyword can only be used within async functions to wait for the completion of asynchronous operations.

Here’s an example illustrating the usage of async and await:

Future<String> createOrderMessage() async {
  var order = await getUserOrder();
  return 'Success!! Your order is: $order';
}

Future<String> getUserOrder() async {
  var val = await Future.delayed(Duration(seconds: 4), () => 'Large Latte');
  return val;
}

void main() async {
  print(await createOrderMessage());
}

In this example, createOrderMessage and getUserOrder are asynchronous functions that return a Future. The main function is marked as async, allowing the use of await to retrieve the result of the asynchronous operation.

Example with a Synchronous Main Function

In cases where the main function is synchronous, we can’t use await directly. Here’s an example illustrating how to handle this scenario:

Future<void> createOrder() async {
  var order = await getUserOrder();
  print('Success!! Your order is: $order');
}

Future<String> getUserOrder() async {
  var val = await Future.delayed(Duration(seconds: 4), () => 'Large Latte');
  return val;
}

void main() {
  createOrder();
}

In this example, we create an asynchronous createOrder function that uses await to wait for the result from getUserOrder. However, since the main function is synchronous, we simply call createOrder() without using await.

By effectively utilizing asynchronous capabilities through Future, async, and await, Dart ensures efficient handling of asynchronous operations in your code.