flutter开发Future与Stream的理解和区别
-
Future特点
- Future是表示一个异步操作的单个结果,只返回一次结果。通常用于处理一次性的异步操作。
- Future通过then()和catchError()方法来处理异步操作的结果和异常。
- Future使用await关键字来等待异步操作完成。
- FutureBuilder:通过监听future值的单次变化进行界面刷新,不需要setState。
Future<String> fetchData() {
return Future.delayed(Duration(seconds: 2), () {
return '数据已经获取';
});
}
void main(){
//1.可以使用then处理future异步结果
fetchData().then((value) {
print(value);
});
//2.可以使用await等待future异步结果
final value = await fetchData();
print(value);
}
-
Stream特点
- Stream表示一系列异步操作的序列,可以返回多个结果。通常用于处理实时流式数据。
- 通过listen()方法来订阅监听和处理异步事件。
- Stream使用async*和yield关键字生成异步事件序列。使用await for关键字等待异步事件序列
- StreamBuilder:通过监听stream值的多次变化进行界面刷新,也不需要setState。
Stream<int> fetchData(int start, int end) async* {
for (int i = start; i >= end; i--) {
await Future.delayed(Duration(seconds: 1));
yield i;
}
}
void main(){
//使用await for 等待stream结果序列
await for (var value in fetchData(10, 0)) {
print(value);
}
}
-
StreamController特点
- StreamController是对stream的管理。内部持有stream,封装了对stream订阅的常规操作包括是否暂停,关闭等等,还可以将单订阅stream(默认是单订阅)转为多订阅stream。
- stream流默认是单订阅的,也就是只能调用一次它的listen()方法进行一次订阅,第二次调用就会报错。如果需要多个地方多次调用呢怎么办?那就需要将单订阅流转为多订阅流,也叫做广播流。这之后才能多次调用listen()方法。
- 单订阅流和广播流主要有两个区别:1. 前者只能调用一次listen()方法,后者可以多次调用listen()方法。2. 单订阅流内部保存着所有的数据,在你订阅(调用listen方法)时会收到所有的数据。而广播流是没有保存数据的,也就是你只能收到订阅之后的数据。
//StreamController内持有stream,相当于创建了一个stream
final StreamController streamController = StreamController();
//关闭
streamController.close();
//调用内部sink的add方法发送一个流数据,然后再通过stream的listen方法订阅,
//因为stream默认是单订阅流,内部保存所有数据,add之后再listen订阅是可以收到的。
streamController.sink.add(100);
streamController.stream.listen((event) {
//能收到100
//也能收到200
});
streamController.sink.add(200);
//再次调用stream.listen方法就会报错,因为这是单订阅流
streamController.stream.listen((event) {});
//将单订阅流转为广播流
final broadcastStream = streamController.stream.asBroadcastStream();
//直接创建一个广播流,内部不会保存所有的数据哦
final StreamController broadcastController = StreamController.broadcast();
broadcastController.sink.add(100);
broadcastController.stream.listen((event) {
//收不到100,这个就是广播流和单订阅流的第二个区别
//能收到200
});
broadcastController.sink.add(200);
//可以再次调用stream.listen方法
broadcastController.stream.listen((event) {
//收不到100
//也收不到200
});
-
StreamSubscription特点
- 使用StreamSubscription对象来对流订阅进行管理,listen方法的返回值就是StreamSubscription对象
//listen方法返回StreamSubscription对象
StreamSubscription subscription = Stream.periodic(...).listen((num) {
print(num);
});
//暂停、恢复、取消订阅
subscription.pause();
subscription.resume();
subscription2.cancel();