dart语言构造函数中如果存在异步方法,编程时如果不注意特殊处理的话,很容易使代码出现未定义行为。例如下面的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
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使用。虽然能够解决异步构造的问题,但总觉得不够优雅。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
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"); } |
输出:
1 2 3 4 |
I/flutter (14941): create() (public factory) I/flutter (14941): _create() (private constructor) I/flutter (14941): async return value: hello I/flutter (14941): done |