2

I'm learning about async and await in Dart. For the most part, it makes sense that it's a way to say that some function will take a while and that the program should run a particular function asynchronously.

What I'm not understanding is how that affects all the "preceding" functions that eventually lead to the given asynchronous function.

For example,

import 'dart:async';

Future<String> firstAsync() async {
  await Future<String>.delayed(const Duration(seconds: 2));
  return "First!";
}

String secondAsync() async {
  var returnVal = await firstAsync();
  return returnVal;
}

void main() {
  var s = secondAsync();

  if (s == "First!") {
    ///run some code...
  }

  print('done');
}
  1. firstAsync returns a future, so it makes sense that the function's return value is Future<String>. Then, secondAsync uses this function. Does that mean that secondAsync must also return Future<String>?

  2. Does main need the async keyword and would I need to change its first line to var s = await secondAsync(); ?

  3. And if so, does that mean that main also needs to be marked as returning Future<void>?

whatwhatwhat
  • 1,991
  • 4
  • 31
  • 50

1 Answers1

2

If my function calls an asynchronous function, does that force me to make my function return a Future?

Not necessarily, but almost always. If your function needs to return a result that depends on the called asynchronous function, then your function is implicitly asynchronous too and must return a Future.

If callers of your function don't need to be notified when your function completes, then your function is "fire-and-forget" and can return void instead of a Future. Or if your function does not depend on the called asynchronous function (i.e., you're calling a fire-and-forget asynchronous function), then your function can return whatever it wants. It's not waiting for anything.

  1. firstAsync returns a future, so it makes sense that the function's return value is Future<String>. Then, secondAsync uses this function. Does that mean that secondAsync must also return Future<String>?

Yes.

  1. Does main need the async keyword and would I need to change its first line to var s = await secondAsync(); ?

Technically no (you could use the raw Future API directly and not use await), but you should prefer using async/await. It's much easier to understand.

  1. And if so, does that mean that main also needs to be marked as returning Future<void>?

Usually there is no caller of main that needs to wait for it complete (and the Dart VM/runtime will wait until the event queue is empty before exiting), so main usually can be considered fire-and-forget and can return void. The current recommendation from the avoid_void_async lint documentation is to not bother having main return a Future.

Having main return a Future could matter if you have a recursive main function or if your .dart file might be imported by another file that directly invokes your main() function. However, those circumstances would be very rare (and probably would be better off avoided anyway by refactoring).

jamesdlin
  • 81,374
  • 13
  • 159
  • 204