1
votes

I'm fairly new to Dart and been trying to understand why a calling function needs to return a future? I get why the called function needs to return a future, but not the calling function itself. This doesn't seem to make sense and confuses the logic. For example, say I wanted:

List<String> someFunct() async {
   final _res = await someFuture();
   return _res.toList();
}

I can't do this without wrapping the calling function's return in a Future that then propagates this async model up the calling tree. The calling function is not a future, so it shouldn't need to return a future.

1
In your example, someFunc cannot return a value to its caller until after someFuture has completed. Since someFunc must wait, someFunc's callers must wait too. Maybe you think that someFunc could just block until someFuture completes, but Dart is single-threaded in each isolate. If someFunc blocked, then someFuture would never be resolved. Maybe you think that someFunc could block and allow someFuture to resolve by spinning its own event loop, but now you'd have nested event loops which are generally bad news (for example, they can lead to unexpected re-entrancy). - jamesdlin

1 Answers

3
votes

An asynchronous function is one which doesn't complete its work immediately when it's called. That's why it returns a Future, which is an object which will eventually make the result available.

All functions must return something when they are called. Dart does not support blocking, where a function simply stops in the middle and lets other code run until it's ready to continue, because that requires having separate stacks, and it can't be efficiently compiled to JavaScript. So an asynchronous function must return something immediately, and that something is a future.

Returning the future allows the calling function to wait until the result is available. It has to, if it needs to use the result.

In your example, someFunct wants to return a list which isn't available until later. It cannot simply return a list immediately, because it doesn't have the list yet. So, it must return a Future<List<String>>.

The one case where you don't need to return a future from an otherwise asynchronous function is when the calling function doesn't care about the result, or it gets the result in some other way, say by it being added to a collection when it's ready. Then you can just return void, and not bother with a future.

In the vast majority of cases, your asynchronous functions must return a future, because they want to return something, and that's all they have available before the real result is ready.