I would like to have nested then callbacks as below:
somemethod1 and somemethod2 inside both functions return future.
Future<T> **somefunctionA**() => ...somemethod1().then((value) => return T);
Future<T> **somefunctionB**() => ...somemethod2.then((value) async {
await **somefunctionA**();
/// then post processing...
}).then((value) => do something);
I have implemented this, but the nested then callback inside somefunctionA never completes.
Instead, the outer then callback to somefunctionB gets called once the future inside somefunctionA completes.
How do I make this work in such a way that the inner then callbacks must be completed before the outer then executes?
Any help would be appreciated.
Related
The issue seems to be around calling a method with a _ before it, such as Future _showFirstPolylineMapMarkers
In my main.dart at the end of a method I call 2 entities, one is within main.dart and works fine, the other is in another Class, _mapItemsExample2.
...
_sendIntermodalDataToSecondScreen(context, mappedValues, dest); //works fine
_mapItemsExample2?.getroute(deplat, deplong, deplocname);
}
});
}
It will pass data to
Future getroute(deplat, deplong, deplocname) async {
print('getroutetest');
_showFirstPolylineMapMarkers(deplat, deplong, deplocname);
}
void _showFirstPolylineMapMarkers(deplat, deplong, deplocname) async {
...
But it goes dead and doesn't print or call _showFirstPolylineMapMarkers
If i replace .getroute... with ._showFirstPolylineMapMarkers(deplat, deplong, deplocname) to call the method directly it shows an error
The method '_showFirstPolylineMapMarkers' isn't defined for the type 'MapItemsExample2'.
If i remove the underscore at the start _ errors go away but it doesnt call it when ran
Any guidance appreciated
Thank you
The _ indicates a private field or method, meaning that it can only be used within the file it's defined in.
It is a good practice to use the _ to make methods private to ensure they're only used where they are defined.
I have a function that calls a Future in it. Now I am not sure if the first function needs to be a future too to await for the data. Here is my code:
FireBaseHandler handler = FireBaseHandler();
saveRows() {
handler.saveRows(plan.planId, plan.rows); ///this is a future
}
In my FireBaseHandler class I have this Future:
final CollectionReference usersCol =
FirebaseFirestore.instance.collection('users');
Future saveRows(String id, data) async {
return await usersCol.doc(myUser.uid).collection('plans').doc(id)
.update({'rows': data});
}
So does the first function needs to be a Future too?
You can have async function inside a sync function. But this way you lose ability to await for the result. And await is allowed only in functions marked as async, which leads us to Future as a the result of that function. So, yes, if you need to wait for the result, both functions have to be Future functions.
Edit:
If you need your wrapper function to be sync, but still be able to retrieve the result from inner async function, you can use a callback:
saveRows(Function(dynamic) callback) {
handler.saveRows(plan.planId, plan.rows).then((result){
callback(result);
});
}
This way the result will be retrieved at any point of time after calling the function (the code is not awaited)
I have an async method. Can I call it from an non-async method? Like the following
My method
void method() async{
await 'something'
}
Case 1
onPressed:() {
method();
}
Case 2
onPressed:() async{
await method();
}
Which of the above is correct? It seems to me two of them is OK. However, the second one I think works much more slower, am I wrong?
In general, the caller of an async function must also be asynchronous if it wants to wait for the call to complete. This makes asynchronous-ness contagious.
In your case, your async function is a "fire-and-forget" function; callers cannot wait for it to complete, so it doesn't matter. Your second case (with await method()) is wrong because you should use await only on Future/FutureOr, but method returns void, so there nothing to wait for. (The Dart analyzer would warn you about this if you have the await_only_futures lint enabled.)
You also could simplify your code further by using a tear-off instead of creating an unnecessary closure:
onPressed: method
From the documentation for the Future.microtask constructor, it says:
* Creates a future containing the result of calling [computation]
* asynchronously with [scheduleMicrotask].
and the documentation for the regular Future constructor states:
* Creates a future containing the result of calling [computation]
* asynchronously with [Timer.run].
I am wondering, what kind of implications do they have on coding, and when should we use one or another?
All microtasks are executed before any other Futures/Timers.
This means that you will want to schedule a microtask when you want to complete a small computation asynchronously as soon as possible.
void main() {
Future(() => print('future 1'));
Future(() => print('future 2'));
// Microtasks will be executed before futures.
Future.microtask(() => print('microtask 1'));
Future.microtask(() => print('microtask 2'));
}
You can run this example on DartPad.
The event loop will simply pick up all microtasks in a FIFO fashion before other futures. A microtask queue is created when you schedule microtasks and that queue is executed before other futures (event queue).
There is an outdated archived article for The Event Loop and Dart, which covers the event queue and microtask queue here.
You can also learn more about microtasks with this helpful resource.
Here is a simple example of how code would run in sequence in terms of how Futures are executed. In the example below, the resulting print statements wouldn't be in alphabetical order.
void main() async{
print("A");
await Future((){
print("B");
Future(()=>print("C"));
Future.microtask(()=>print("D"));
Future(()=>print("E"));
print("F");
});
print("G");
}
The resulting print statements would end up in the order shown below. Notice how B, F, and G gets printed first, then C, then E. This is because B,F, and G are synchronous. D then gets called before C and E because of it being a microtask.
I saw many people's code use async keyword in a function without an await keyword in the function body. Even some official flutter example code do this. I have no idea why. What is the point? Is this a mistake or having a purpose?
Normally, I just remove the async keyword from those code and everything will run without any problems. Can some dart expert clarify that if there is a purpose for a function which has the async keyword but NO await keyword? Or is this just their mistake?
async is sometimes used to simplify code.
Here are some examples:
Future<int> f1() async => 1;
Future<int> f1() => Future.value(1);
Future<void> f2() async {
throw Error();
}
Future<void> f2() {
return Future.error(Error());
}
According to official Dart Language tour, async executes synchronously until it finds await keyword :
Note: Although an async function might perform time-consuming operations, it doesn’t wait for those operations. Instead, the async function executes only until it encounters its first await expression (details). Then it returns a Future object, resuming execution only after the await expression completes.