void f()
and Future<void> f()
are not identical. (The presence of the async
keyword doesn't actually matter. The async
keyword primarily enables the use of the await
keyword in the function body.)
void f()
declares a function that returns nothing. If it does asynchronous work, then that work will be "fire-and-forget": there is no opportunity for the caller of f
to wait for it to finish.
In contrast, Future<void> f()
declares a function that returns a Future
that the caller can wait for (either by using await
or by registering a Future.then()
callback). There's no value returned by the asynchronous work, but callers can determine when it is finished.
Functions marked with async
usually should return a Future
. If you have a function that does asynchronous work that produces an actual value (such as an int
), then the caller must wait for that value to be computed before it can be used. That function therefore must return a Future
.
As a special case, an async
function can return void
instead of Future<void>
to indicate that it is fire-and-forget.
myVoid
usesawait
for all it's async calls (i.e. it basically becomes a sync method), then it is possible formain
to wait formyVoid
to finish... right? I think that's what got me confused, since I encountered such a function and couldn't figure out why it was returningvoid
instead ofFuture<void>
. Especially what confused me was that IntelliJ hints "Await only futures." - but it is still possible to await the function even though it returnsvoid
, just the same as if changing it toFuture<void>
... – Oppose