Let's assume that an initialization of MyComponent in Dart requires sending an HttpRequest to the server. Is it possible to construct an object synchronously and defer a 'real' initialization till the response come back?
In the example below, the _init() function is not called until "done" is printed. Is it possible to fix this?
import 'dart:async'; import 'dart:io'; class MyComponent{ MyComponent() { _init(); } Future _init() async { print("init"); } } void main() { var c = new MyComponent(); sleep(const Duration(seconds: 1)); print("done"); }
Output:
done init
Just call getWRitings() or whatever async method and don't await it. It won't be done when the constructor ends, but that's ok. Don't use its value there, instead - use its value in another method and call that.
The problem arises when you're trying to call such an asynchronous method from a class constructor: you can't use the await keyword inside the constructor. As long as you're only using methods which don't return a value, you can get away with it by just calling them without await, but that's not the right way to do it.
Summary of asynchronous programming in Dart Asynchronous function is a function that returns the type of Future. We put await in front of an asynchronous function to make the subsequence lines waiting for that future's result. We put async before the function body to mark that the function support await .
Here, the function variable type just needs to specify that it returns a Future: class Example { Future<void> Function() asyncFuncVar; Future<void> asyncFunc() async => print('Do async stuff...'); Example() { asyncFuncVar = asyncFunc; asyncFuncVar(). then((_) => print('Hello')); } } void main() => Example();
A constructor can only return an instance of the class it is a constructor of (MyComponent
). Your requirement would require a constructor to return Future<MyComponent>
which is not supported.
You either need to make an explicit initialization method that needs to be called by the user of your class like:
class MyComponent{ MyComponent(); Future init() async { print("init"); } } void main() async { var c = new MyComponent(); await c.init(); print("done"); }
or you start initialization in the consturctor and allow the user of the component to wait for initialization to be done.
class MyComponent{ Future _doneFuture; MyComponent() { _doneFuture = _init(); } Future _init() async { print("init"); } Future get initializationDone => _doneFuture } void main() async { var c = new MyComponent(); await c.initializationDone; print("done"); }
When _doneFuture
was already completed await c.initializationDone
returns immediately otherwise it waits for the future to complete first.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With