Search code examples
dartdart-async

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


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?


Solution

  • 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.