I don't really understand how the await/async mechanism (in dart but I guess the question is relevant for any language actually). I'm using the sqfentity library to manage a small database.
this lib is providing a select().toList() function which will query some DB rows and returns it as a list of object.
the returned function is actually returning a Future<List> allowing to run the query asynchronously.
I'm working with local DB so I'm not really concerned by access time issues, so I'd like to write a function returning a list,once the query has finished:
List<Event> get_list() async{
return await Event()
.select()
.toList()
}
The problem is that an async function must return a Future<> object. However, if I understand well, the await will "wait" for the toList() function to finishes before returning, so I don't understand why I can't just return the List object.
In order to do my job, I used the fact that in dart, parameters are passed by reference, so I wrote some intermediate function
void fillList(List<Event> lst){
lst.addAll(await Event()
.select()
.toList())
}
List<Event> get_list() {
List<Event> lst;
fillList(lst);
return lst;
}
which seems really not natural and probably a wrong way to do things. Any explanation on how to deal with await in dart ?
thanks!
CodePudding user response:
I am not very sure if I understood the question, but it depends on the return type of Event().select();
. If it returns a Future
, then you need to use the async/await combination, or the then
callback. Otherwise, you can just return a list of Event
directly.
You can also do something like:
List<Event> get_list(){
final List<Event> events = [];
// If Event().select() returns a Future
Event()
.select().then((result){
events.addAll(result.toList());
});
return events;
}
But the issue with this is that while Event().select()
is still loading, the function will return an empty list, then when items are loaded, the function will come back and fill the list with the returned items. That's why something like:
Future<List<Event>> get_list() async{
final events = await Event().select();
return events.toList();
}
Is kind of better because if you want for example to show a spinner while items are loading, you can do that, also you can easily catch errors.
CodePudding user response:
However, if I understand well, the await will "wait" for the toList() function to finishes before returning, so I don't understand why I can't just return the List object.
When you do:
Future<Result> foo() async {
var intermediateResult = await someAsynchronousOperation();
var result = doOtherStuff(intermediateResult);
...
return result;
}
await
provides the appearance of pausing execution of foo
until someAsynchronousOperation()
completes. It does not pause your entire program. The point of an asynchronous operation is to allow the rest of your program to continue executing while you are waiting for it to complete. This allows your program to continue to respond to user input.
Whenever you use await
, it's actually syntactic sugar for returning a Future
:
Future<Result> foo() {
return someAsynchronousOperation().then((someIntermediateResult) {
var result = doOtherStuff(intermediateResult);
...
return result;
});
}
foo()
calls someAsynchronousOperation()
(which itself returns a Future
), registers a .then()
completion callback on it to execute doSomeOtherStuff()
later. foo()
then immediately returns the resulting Future
to its own caller.
void fillList(List<Event> lst){ lst.addAll(await Event() .select() .toList()) } List<Event> get_list() { List<Event> lst; fillList(lst); return lst; }
That will not work.
await
can be used only in a function declared withasync
.- Because
fillList
depends on aFuture
, it is inherently asynchronous. However, by declaring it to returnvoid
instead of aFuture
, it is impossible for callers to be notified whenfillList
completes. - Once you fix
fillList
to return aFuture
,get_list
needs to wait for thatFuture
to complete before returninglst
. Sinceget_list
would need to depend on aFuture
, it too is inherently asynchronous. (Asynchronous functions are contagious.)