Dart:总结开发中 `Stream` 用法及场景

StreamFutureDart:async提供的核心API,都是为处理异步事件而生。今天我们来重点聊聊 StreamStream 是一系列异步事件的序列,可以理解成一个异步的 Iterable,不同的是当你向 Iterable 获取下一个事件时它会立即给你,但 Stream 则不会立即给你,而是在它准备好时告诉你。

如何理解 Stream

小编在开发中,把 Stream 看作一个 工厂机器

  • 它有一个入口,可以接收指令(数据),这个机器不知道入口什么时候会放东西进来
  • 可再机器内部,根据指令,进行数据加工 (转化层,也可做逻辑层)
  • 它有一个出口,当内部指令操作完毕后,会有产品从那出来,我们也不知道什么时候产品会从出口出来


两种类型的工作流

  • 类型1:往 Stream 发送数据指令
  • 类型2:定制转化层,监听 Stream

如何使用 Stream?

创建 Stream

这里,小编介绍四种开发中常见的Stream创建方式

1. 通过定时的方式创建,每秒往stream流内发送数据1~15,使用take(15)做了限制,只轮询15次
var stream = Stream<int>.periodic(const Duration(seconds: 1), (value) => value).take(15);
2. 根据现有数据源创建
var stream = new Stream<int>.fromIterable([1, 2, 3, 4, 5]);
3. 从零创建,使用 yield 关键字,这种方式较为常用,Bloc里面就是使用的这种方式
// 模拟每秒往流里注入数据
Stream<int> createStream(int maxCount) async* {
  int i = 0;
  while (true) {
    await Future.delayed(Duration(seconds: 1));
    yield i++;
    if (i == maxCount) break;
  }
}
4. 从零创建,使用 StreamController 方式。开发中常用这种方式实现广播效果,文末扩展。
// 模拟每秒往流里注入数据
Stream<int> createStream(int maxCount) {
  var controller = new StreamController<int>();
  int i = 0;
  while (true) {
    controller.add(i);
    if (i == maxCount) {
      controller.close();
      break;
    }
  }
  return controller.stream;
}
Stream分为两种类型:
  • 单一模式:controller.stream 同时只能设置一次监听
  • 广播模式:controller.broadcast().stream 同时可设置多个监听
订阅监听 Stream

Stream 底层提供 listen() 方法:

//自来SDK
StreamSubscription<T> listen(void onData(T event)?,
    {Function? onError, void onDone()?, bool? cancelOnError});

开发中,常见用法如下:
订阅监听

Stream<int> stream = createStream(15); //生成 1~15 数据的内容流

StreamSubscription<int> subscription;

void onData(int value){
  //具体的业务处理,比如打印,依次打印 1 到 15
  print(value);
}
//开始监听
subscription = stream.listen(onData);

暂停监听

subscription.pause();

恢复监听

if(subscription.isPaused){
  subscription.resume();
}

取消监听

subscription.cancel();
介绍完 Stream 的创建和订阅监听,最后我们来看看 Stream 的转换层如何实现

下面通过代码示例,演示两种方式,将int 类型的 Stream 数值乘以2倍数,并转化成 String 类型的 Stream

1. 使用 iterable 自带函数
Stream<String> transformStream1(Stream<int> stream) {
  //方式1:
  // return stream.expand<String>((element) => [(element * 2).toString()]);
  
  //方式2:
  Future source = stream.map((x) => (x * 2).toString()).toList();
  return new Stream<String>.fromFuture(source);
}
2. 使用 transformer 的方式
Stream<String> transformStream2(Stream<int> stream) {
  final transFormer = StreamTransformer<int, String>.fromHandlers(
    handleData: (value, sink) {
      sink.add((value * 2).toString());
    },
  );
  return stream.transform<String>(transFormer);
}
开发中Stream 常用的应用场景
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容