Dart: `return future` vs `async return future`

45 Views Asked by At

I'm running this code:

import 'dart:async';

void main() {
  final c = Future.value(); // Other constructors and `Completer.future` all yield same results.
 
  print(c == sync(c));
  print(c == aSync(c));
}

Future sync(Future future) {
  return future;
}

Future aSync(Future future) async {
  return future;
}

And I get as output a seemingly strange result:

true
false

I know how futures work in Dart, and that technically we create a new Future instance for every async function, but it just seems strange how we return the same object in both cases, yet with different results.

Is this intended behaviour?

1

There are 1 best solutions below

0
jamesdlin On BEST ANSWER

It's expected behavior. One of the things that the async keyword does is to transform return statements in the function body to return Futures. If the function body already returns a Future, don't be surprised if it gets transformed into a new Future.

What's supposed to happen is that an existing Future directly returned within an async function is implicitly awaited. That is:

Future<T> aSync<T>(Future<T> future) async {
  return future;
}

is supposed to be equivalent to:

Future<T> aSync<T>(Future<T> future) async {
  return await future;
}

Apparently this is what's intended by the Dart language specification but isn't what happens in practice. Not having the implicit await can make error-handling confusing if the Future fails.

There also is discussion about disallowing async functions from directly returning Futures and to require that they explicitly await any returned Futures instead.