dart第三篇:Future和Stream
和nodejs一样,dart没有线程和进程的概念,而是采用单线程+事件循环的设计模式。和nodejs一样,dart中的异步采用async和await。
async用于定义异步方法,async关键字放在花括号前面。
Future<int> getNum() async { int a = 0; for (var i = 0; i < 1000000; i++) { a = a + i; } return a; }
await用于调用async的方法,把异步变成同步。await必须在async方法使用。
Future<String> doSomeLongTask() async { int a = await getNum(); return "a=$a"; }
Stream是流,代表一系列元素,支持泛型。常用的生成Stream实例的方法有:
1、调用Stream自带的几个静态方法,如Stream.periodic()每隔指定时间吐一个元素,Stream.value()生成一个只有一个元素的流,Stream.fromFuture(),Stream.fromFutures(),Stream.fromIterable()。
2、获取StreamController实例的stream属性。
通过调用StreamController()无参构造方法可以获得一个StreamController实例,然后直接打点获取其stream属性就可以得到其对应的Stream实例。注意此时这个Stream实例只能被监听一次,否则会报错。如果想让Stream实例能被监听多次,则需要调用StreamController的broadcast()静态方法获取StreamController实例。
调用StreamController实例的add()方法来往stream中放数据,调用StreamController实例的close()方法关闭流,流关闭后就不能再往其中放数据了,否则会报错。
3、调用Future实例的asStream()方法。
我们可以调用Stream实例的listen()方法来监听流,在获取到流中的数据时,执行一些操作,如打印。
_controller.stream.listen((data) { print(data); });
Stream还有很多和java中的流一样的方法,如where()实例方法可以对Steam进行过滤。
async和Future配套,async*和Stream配套,如下
Stream<int> countForOneMinute() async* {
for (int i = 1; i <= 5; i++) {yield i;
}
}
main() async {
await for (int i in countForOneMinute()) {
print(i);
}
print("over");
}
Stream是流,需要用await for遍历。如果要跳出,需要用break或者return。await for和await一样,也必须位于async方法中。
创建对象和java创建对象的方式一样,如有个Person类,有name和age属性,有一个全参的构造方法,则可以用new person("zhangsan",14)创建对象,new关键字可以省略,编译器会提醒。
dart中类可以用extends继承一个类,也可以用implements实现接口。
dart有一个mixin关键字,用于解决单继承问题。如果一个类已经继承了一个类,但是又想用另一个类的方法,则可以使用mixin。mixin是混入的意思,后面跟一个类名,用于定义类,如mixin Person {}。mixin类不能extends其他类,也不能实例化。我们可以在定义另一个类时用with关键字关联Person,如class Doctor with Person{}。mixin类既可以定义一般方法,也可以定义抽象方法,让with它的类去实现。假设Person定义了一个find()方法,那么doctor实例可以调用find()方法。mixin类也不能with其他mixin类。
还有一个on关键字,和mixin搭配,后面也是跟一个类名,格式是mixin A on B {},用于限定只有B的子类才能with A,如mixin Person on Animal {}。如果想让Doctor with Person,Doctor必须先extends Animal,即class Doctor extends Animal with Person {}。
mixin后面还可以跟class关键字,后面再跟类名,这样定义的类兼具mixin类和普通类的特性,即像mixin类那样不能继承其他类、不能实例化、不能with其他mixin类,也像普通类那样,不能on某个类。