In Dart, both the async and async* keywords are used for asynchronous operations, but they differ in their usage scenarios and return types.
async
When you use the async keyword in a function definition, it indicates that the function is asynchronous and returns a Future. Within such a function, you can use the await keyword to pause execution until an asynchronous operation completes and retrieve its result.
Example:
dartFuture<String> fetchUserOrder() async { var order = await fetchAsyncFromDatabase(); return 'Your order is: $order'; }
In the above example, fetchAsyncFromDatabase() is an asynchronous function returning a Future of database query results. Using the await keyword, you can write code in a nearly synchronous manner, waiting for the result before proceeding.
async*
Functions defined with the async* keyword are generator functions that return a Stream. This allows the function body to use the yield and yield* keywords to provide multiple values, which are sent one by one over time.
Example:
dartStream<int> countStream(int to) async* { for (int i = 1; i <= to; i++) { await Future.delayed(Duration(seconds: 1)); yield i; // Send numbers one by one } }
In this example, the countStream function generates numbers every second until reaching the specified limit. Each yield operation effectively waits for the completion of a Future.delayed, simulating a time-consuming operation.
Summary
- Functions defined with the
asynckeyword return aFuture, suitable for a single asynchronous result. - Functions defined with the
async*keyword return aStream, suitable for generating multiple asynchronous events.
In practical applications, choosing between async and async* depends on whether you need a single or multiple asynchronous results from the function.