dart语言构造函数中如果存在异步方法,编程时如果不注意特殊处理的话,很容易使代码出现未定义行为。例如下面的代码:
class MyComponent{
MyComponent() {
init();
}
init()async{
var ret = await _init();
print('$ret');
}
_init(){
return Future.delayed(new Duration(seconds: 2), () {
return "hello";
});
}
}
void main() {
var c = new MyComponent();
print("done");
}
本意是想先输出“hello“ 然后再输出”done",然而输出顺序刚好相反。原因在于init是异步方法,本应该在调用前使用await等待异步方法返回。然而在构造函数中是无法使用await的。那么该如何处理呢?下面是一种方法,使用工厂函数产生类的对象。而工厂函数是异步的,需要配合await使用。虽然能够解决异步构造的问题,但总觉得不够优雅。
import 'dart:async';
import 'dart:io';
class MyComponent{
/// Private constructor
MyComponent._create() {
print("_create() (private constructor)");
// Do most of your initialization here, that's what a constructor is for
//...
}
_complexAsyncInit(){
return Future.delayed(new Duration(seconds: 2), () {
return "hello";
});
}
/// Public factory
static Future<MyComponent> create() async {
print("create() (public factory)");
// Call the private constructor
var component = MyComponent._create();
// Do initialization that requires async
var ret = await component._complexAsyncInit();
print("async return value: $ret");
// Return the fully initialized object
return component;
}
}
void main() async {
var c = await MyComponent.create();
print("done");
}
输出:
I/flutter (14941): create() (public factory)
I/flutter (14941): _create() (private constructor)
I/flutter (14941): async return value: hello
I/flutter (14941): done