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?
It's expected behavior. One of the things that the async
keyword does is to transform return
statements in the function body to return Future
s. 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 await
ed. 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 Future
s and to require that they explicitly await
any returned Future
s instead.