When do I need to state the return type of an async function as a future object? When do I need to state the return type of an async function as a future object? dart dart

When do I need to state the return type of an async function as a future object?


Yes, using the async keyword will make the function automatically return a Future.

It is always better to explicitly declare the return type of a function even for void functions, if not, the compiler will interpret the function as having a dynamic return type.

It will also help/make it easier for the reader to know the return type of the function.

Also, you need to wrap your object in a Future in an async function like so:

Future<Object> getObject() async {  final object = await timeConsumingTask();  return object;}

If you write it like this without wrapping it:

Object getObject() async {  final object = await timeConsumingTask();  return object;}

The compiler throws the error: Functions marked 'async' must have a return type assignable to 'Future'.

For void functions, it seems that you do not have to wrap the return type in a Future, so something like this is fine:

void doSomething() async {  await timeConsumingTask();  print('done');}


Let's consider a method gatherNewsReports() which only returns a Future<String>. The string value of the Future from gatherNewsReports. Implementation of gatherNewsReports.

// Imagine this is a slow method. Takes time to finishFuture<String> gatherNewsReports() => Future.delayed(Duration(seconds: 1), () => news);

We will go through all possible combinations of method call with Future and async. The method I am going to make is called getDailyNewsDigest

Option-1:

One definition of the method might be as with Future and async given in method call:

Future<String> getDailyNewsDigest() async {  var str = await gatherNewsReports();  print(str);  return str;}

Remember that gatherNewsReports() which returns a Future<String>. We are just returning whatever gatherNewsReports returns.

Usage:

main() async {  await getDailyNewsDigest();  print('call done');}

Output:

<gathered news goes here>call done

Comments: This seems straight forward. You just call the method and await on it. Remember we are using await keyword when calling getDailyNewsDigest from the main method. So, unless we pass 1 second, i.e, the duration of time it requires the Future to execute. If we didn't use the await keyword then the output sequence will be reversed.

Option 2

One definition of the method might be as with Future given and async NOT given in method call:

Future<String> getDailyNewsDigest() {  var str = await gatherNewsReports();  print(str);  return str;}

This is not valid because you can't call a method with await, in this case gatherNewsReports. This is invalid.

Option-3

We define the method might be with Future NOT GIVEN and async given in method call. Since the return type is going to be void we will not return anything (N.B: If we try to return anything other than a Future or a void then we get an error):

void getDailyNewsDigest() async {  var str = await gatherNewsReports();  print(str);}

This is a valid method definition. Now, since the method is declared as void we can't await on the main method. The updated main method.

main() async {  getDailyNewsDigest(); // We can't await on it since return is void  print('call done');}

Output:

call done<gathered news goes here>

As you can see since the method getDailyNewsDigest is not called without await the output is reversed. We are no longer waiting for the getDailyNewsDigest to finish.

Option-4

We define the method might be with Future<Void> instead of Future<String> and async given in method call:

Future<void> getDailyNewsDigest() async {  var str = await gatherNewsReports();  print(str);  return;}

Now in our main method we can use the await keyword again for calling getDailyNewsDigest.

main() async {  await getDailyNewsDigest(); // We can await on it since return is Future<Void> but don't care on the output since it returns nothing  print('call done');}

These are 4 combinations I can think of.

As for this:

But my instructor kind of confused me, sometimes she had a future as the return type and another time she didn't put it and they were both async functions.

Declaring a method with either Future means you can await on it, declaring it with void means you can't await in it. You can of course choose not to await on a Future if you don't care to do anything with the output of the Future. If you write your code in such a way that you don't want anyone to depend on the output of the method, i.e, the Future we would otherwise return from the method will be handle d by itself, all we care about is firing-it-and-continue with our work; in that case we should define our method with return type void.