Dart | Stream的理解 Part2

111 阅读2分钟

image.png 开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情

前言

上一篇文章中,我们具体介绍了Stream的一些比较简单的应用。在这篇文章中,我会继续给大家讲解Dart的Stream的其他构造方式以及使用方法。

正文

1.获取Stream对象的方法

首先,获取Stream对象的方法主要分为以下的5种:

  1. Stream.fromFuture
  2. Stream.fromFutures
  3. Stream.fromIterable
  4. 直接使用StreamController
  5. 通过生成器创建流。async*

其中第四点已经在上一篇文章进行了讲解。其余的点我们陆续的几篇文章会进行介绍。

2.Stream.fromFuture

如其名,是通过Future对象来获取Stream。至于什么是Future,我们后面再进行介绍。

话不多说,我们先上代码。

Future<String> getData() async {
      return Future.delayed(Duration(milliseconds:10),(){
        return 'Hello, World!';
      });
    }
void main() {
    Future<String> fu = getData();
    Stream<String> s = Stream.fromFuture(fu);
    s.listen((event) {
      print(event);
    },onDone: (){
      print("done");
    });
    print("finish");
}

控制台输出

finish
Hello, World!
done

可以看到,当 getData 这个函数执行完以后,Stream对象才拿到了流过来的数据,当拿到数据以后,这个Stream就完成他的任务了。

3.Stream.fromFutures

void main() {
  Stream.fromFutures([
    Future.delayed(Duration(seconds: 1), () {
      return "hello";
    }),
    Future.delayed(Duration(seconds: 2),(){
      return "world";
    }),
    Future.delayed(Duration(seconds: 3),(){
      throw AssertionError("错误");
    }),
    Future.delayed(Duration(seconds: 3), () {
      return "I'm Jalor";
    })
  ]).listen((data){
    // 每当一个异步任务成功执行完会回调一次,拿到return的数据
    print(data); 
  }, onError: (e){
    print(e.message); // 每当一个异步任务发生异常会回调一次
  },onDone: (){
    print("done"); // 所有异步任务都结束时回调
  });
}

控制台打印:

hello
world
错误
I'm Jalor
done

第一秒打印hello,第二秒打印了world,第三秒打印错误 I'm Jalor done。只有所有的数据都流完了,才会执行done。

3. Stream.fromIterable

void main() {
  Stream.fromIterable([1, 2, 3, 5, 6, 7]).listen((data){
    // 每当一个异步任务成功执行完会回调一次,拿到return的数据
    print(data); 
  }, onError: (e){
    print(e.message); // 每当一个异步任务发生异常会回调一次
  },onDone: (){
    print("done"); // 所有异步任务都结束时回调
  });
}

控制台打印:

1
2
3
5
6
7
done

可以看到是逐个逐个输出的。

5.async*

void main() {
  Stream asynchronousNaturalsTo(n) async* {
    int k = 0;
    while (k < n) yield k++;
  }
  asynchronousNaturalsTo(10)
  .listen((data){
    // 每当一个异步任务成功执行完会回调一次,拿到return的数据
    print(data); 
  }, onError: (e){
    print(e.message); // 每当一个异步任务发生异常会回调一次
  },onDone: (){
    print("done"); // 所有异步任务都结束时回调
  });
}

控制台打印与第三个差不多。