flutter开发Future与Stream的理解和区别

flutter开发Future与Stream的理解和区别

  • Future特点

    1. Future是表示一个异步操作的单个结果,只返回一次结果。通常用于处理一次性的异步操作。
    2. Future通过then()和catchError()方法来处理异步操作的结果和异常。
    3. Future使用await关键字来等待异步操作完成。
    4. 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特点

    1. Stream表示一系列异步操作的序列,可以返回多个结果。通常用于处理实时流式数据。
    2. 通过listen()方法来订阅监听和处理异步事件。
    3. Stream使用async*和yield关键字生成异步事件序列。使用await for关键字等待异步事件序列
    4. 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特点

    1. StreamController是对stream的管理。内部持有stream,封装了对stream订阅的常规操作包括是否暂停,关闭等等,还可以将单订阅stream(默认是单订阅)转为多订阅stream。
    2. stream流默认是单订阅的,也就是只能调用一次它的listen()方法进行一次订阅,第二次调用就会报错。如果需要多个地方多次调用呢怎么办?那就需要将单订阅流转为多订阅流,也叫做广播流。这之后才能多次调用listen()方法。
    3. 单订阅流和广播流主要有两个区别: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特点

    1. 使用StreamSubscription对象来对流订阅进行管理,listen方法的返回值就是StreamSubscription对象
//listen方法返回StreamSubscription对象
 StreamSubscription subscription = Stream.periodic(...).listen((num) {
    print(num);
  });

//暂停、恢复、取消订阅
subscription.pause();
subscription.resume();
subscription2.cancel();
posted @ 2024-02-18 17:27  yongfengnice  阅读(58)  评论(0编辑  收藏  举报