Flutter Stream的使用

首先,来了解一下stream是什么

  • 异步数据事件的来源。
  • 流提供了一种接收一系列事件的方法。每个事件要么是一个数据事件,也称为流的元素,要么是一个错误

    事件,即某事已失败的通知。当流发出所有事件时,单个“完成”事件将通知监听器已达到结束。
  • 您通过调用异步函数生成流,然后返回流。消耗该流将导致函数发出事件,直到它结束,流关闭。您使用async或async函数中可用的await for循环来消耗流,或者在async函数中使用b yield直接转发其事件

Stream的四大要素

  • StreamController:作为整个流的控制器
  • StreamSink:流事件入口
  • Stream:事件源
  • StreamSubscription:订阅管理

订阅模式

  • Stream分为单订阅和多订阅模式
  • 一般创建的Stream都是单订阅模式,只能被监听一次,在创建StreamController时添加broadcast使其变为多订阅模式
  StreamController controller = StreamController.broadcast();

创建流的方式

StreamController

StreamController controller = StreamController.broadcast(onCancel: () {
print('onCancel');
}, onListen: () {
print('onListen');
});
late Stream stream;
late StreamSink sink;
late StreamSubscription sub;
int count = 0; @override
void initState() {
super.initState();
stream = controller.stream;
sink = controller.sink;
sub = stream.listen((event) {
print(event);
});
} @override
void dispose() {
super.dispose();
controller.close();
sub.cancel();
} add() {
count++;
sink.add(count);
}
  • 通过StreamBuilder来接收数据
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('StreamPage'),
),
body: StreamBuilder(
stream: stream,
initialData: count,
builder: (_, snapshot) {
return Text('$count');
}),
floatingActionButton: IconButton(
icon: Icon(Icons.add),
onPressed: () => add(),
),
);
}
  • 点击floatingActionButton,控制台打印
flutter: onListen
flutter: 1
flutter: 2
flutter: 3
flutter: 4
flutter: 5
flutter: 6
flutter: 7
flutter: 8
flutter: 9
flutter: 10

FromFuture

首先创建一个Future函数

Future<String> fromFuture() async {
await Future.delayed(Duration(seconds: 1), () {});
return 'fromFuture';
}

通过FromFuture工厂函数创建流

streamFromFuture() {
Stream stream = Stream.fromFuture(fromFuture());
stream.listen((event) {
print('Stream.fromFuture $event');
}).onDone(() {
print('Stream.fromFuture onDone');
});
return stream;
}

FromFutures

通过FromFutures工厂函数创建流,顾名思义,就是通过一个包含多个Future的Iterable创建流

streamFromFutures() {
Stream stream =
Stream.fromFutures([fromFuture(), fromFuture(), fromFuture()]);
stream.listen((event) {
print('Stream.fromFutures $event');
}).onDone(() {
print('Stream.fromFutures onDone');
});
return stream;
}

FromIterable

通过集合迭代对象创建流

streamFromIterable() {
final List<String> iterable = ['1', '2', '3', '4', '5'];
Stream stream = Stream.fromIterable(iterable);
stream.listen((event) {
print('Stream.fromIterable $event');
}).onDone(() {
print('Stream.fromIterable onDone');
});
return stream;
}

periodic

创建以 [周期] 间隔重复发出事件的流。

streamFromPeriodic() {
Stream stream = Stream.periodic(Duration(seconds: 1), (i) => i + 1);
stream.listen((event) {
print('Stream.periodic $event');
}).onDone(() {
print('Stream.periodic onDone');
});
return stream;
}

async*

通过async*标记函数直接创建

Stream<int> countStream() async* {
for (var i = 0; i < 100; i++) {
count++;
await Future.delayed(Duration(seconds: 1), () {});
yield count;
}
}

部分操作方法

skip

  • 跳过此流中的第一个 [2] 数据事件。
  • 返回一个流,该流发出的事件与此流在同时侦听时发出的事件相同,只是不会发出第一个 [2] 数据事件。当此流完成时,返回的流即告完成。
stream.skip(2);

skipWhile

  • 跳过此流中的数据事件,同时它们与 [i>2] 匹配。
stream.skipWhile((i)=>i>2);

take

  • 最多提供此流的第一个 [2] 数据事件。
  • 返回一个流,该流发出的事件与此流同时侦听时将发出的事件相同,直到此流结束或发出 [count] 数据事件,此时返回的流完成。
stream.take(2);

takeWhile

  • 在 [ i > 2] 条件满足时转发数据事件。
  • 返回一个流,该流提供与此流相同的事件,直到数据事件 [ i > 2] 不满足。当此流完成时,或者当此流首次发出未通过 [test] 的数据事件时,将完成返回的流。
stream.takeWhile((i) => i > 2);

where

  • 从此流创建一个丢弃某些元素( i > 2)的新流。
  • 新流发送与此流相同的错误和完成事件,但它仅发送满足 [test] 的数据事件。
stream.where((i) => i > 2);

map

  • 将此流的每个元素转换为新的流事件。
  • 创建一个新流,该流使用 [ i > 2] 函数将此流的每个元素转换为新值,并发出结果。
stream.map((i) => i > 2);

更多方法请移步

Stream

Flutter Stream的使用的更多相关文章

  1. Flutter响应式编程 - Stream

    1.前言 在Dart库中,有两种实现异步编程的方式(Future和Stream),使用它们只需要在代码中引入dart:async即可. 本文主要介绍Stream的相关概念及利用其异步特性来实现简单的响 ...

  2. Flutter 异常处理之图片篇

    背景 说到异常处理,你可能直接会认为不就是 try-catch 的事情,至于写一篇文章单独来说明吗? 如果你是这么想的,那么本篇说不定会给你惊喜哦~ 而且本篇聚焦在图片的异常处理. 场景 学以致用,有 ...

  3. Flutter 即学即用系列博客——09 EventChannel 实现原生与 Flutter 通信(一)

    前言 紧接着上一篇,这一篇我们讲一下原生怎么给 Flutter 发信号,即原生-> Flutter 还是通过 Flutter 官网的 Example 来讲解. 案例 接着上一次,这一次我们让原生 ...

  4. 当Flutter遇到节流与防抖

    相信web前端的开发者都或多或少的遇到过节流与防抖的问题.函数节流和函数防抖,两者都是优化执行代码效率的一种手段.在一定时间内,代码执行的次数不一定是越多越好.相反,频繁的触发或者执行代码,会造成大量 ...

  5. websocket flutter

    https://stackoverflow.com/questions/51077233/how-can-i-use-socket-in-flutter-app import 'dart:io'; i ...

  6. (转)flutter 新状态管理方案 Provide (一)-使用

    flutter 新状态管理方案 Provide (一)-使用     版权声明:本文为博主原创文章,基于CC4.0协议,首发于https://kikt.top ,同步发于csdn,转载必须注明出处! ...

  7. flutter的webview案例

    flutter 加载webview 安装插件  flutter_webview_plugin: ^0.2.1 从listview点击item跳转页面加载详情页案例 import 'dart:async ...

  8. Flutter从零到∞学习笔记

    有状态widget:StatefulWidget和无状态widget:StatelessWidget 前者不需要实现Widget build(BuildContext context). 具体的选择取 ...

  9. Flutter 知识点

    Flutter:一个移动应用开发框架,它使用 Dart.C++.Skia 开发,对外提供了完全不依赖系统平台的 Widget 的能力,只通过自绘图形的方式工作,具有极其优秀的跨平台性.目前已经支持了 ...

  10. flutter 自己整理

    2018-05 资料 常见问题解决处 https://flutter.io/flutter-for-android/ 起步 api widget https://flutter.io/docs/ 其他 ...

随机推荐

  1. std::vector 和 std::map 都支持以下比较运算符

    在 C++ 标准库中,std::vector 和 std::map 都支持以下比较运算符: ==(相等运算符) !=(不等运算符) <(小于运算符) <=(小于等于运算符) >(大于 ...

  2. 解决数据库表的字段id中间自增断层问题(删除自增主键其中的任意一条数据后,再次插入数据发现id排序出现问题)

    万能解决办法: 先将该表的id字段删除,然后再重新按照见表需求创建该字段 注意!!!!!!!!!!!!! 注意!!!!!!!!!!!!! 注意!!!!!!!!!!!!! 删除之前一定要复制建表时候的S ...

  3. 基于Jenkins + Argo 实现多集群的持续交付

    作者:周靖峰,青云科技容器顾问,云原生爱好者,目前专注于 DevOps,云原生领域技术涉及 Kubernetes.KubeSphere.Argo. 前文概述 前面我们已经掌握了如何通过 Jenkins ...

  4. ARM 版 OpenEuler 22.03 部署 KubeSphere v3.4.0 不完全指南

    作者:运维有术 前言 知识点 定级:入门级 KubeKey 安装部署 ARM 版 KubeSphere 和 Kubernetes ARM 版 KubeSphere 和 Kubernetes 常见问题 ...

  5. 为你的Windows用户设置无边框半透明头像

    步骤一:锁定头像 Win+R输入gpedit.msc进入组策略编辑器,按图中所示,选择"计算机管理->管理模板->用户账户设定",将里面唯一选项"对所有账户使 ...

  6. mini-web 框架添加路由

    阅读目录 1.mini web框架-4-路由 2.伪静态.静态和动态的区别 3.mini-web框架-实现伪静态url 4.准备股票数据 5.mini-web框架-从mysql中查询数据 6.mini ...

  7. 负载均衡在web系统中的应用

    在日常的架构设计与开发中,常用的负载均衡算法主要分为静态和动态两类.静态负载算法以固定的频率分配任务不考虑服务器的状态信息,如轮询法.随机法等:动态负载均衡算法以服务器的实时负载状态信息来决定任务的分 ...

  8. 3.20 什么是环境变量,Linux环境变量有哪些?

    变量是计算机系统用于保存可变值的数据类型,我们可以直接通过变量名称来提取到对应的变量值.在 Linux 系统中,环境变量是用来定义系统运行环境的一些参数,比如每个用户不同的家目录(HOME).邮件存放 ...

  9. Docker制作私有镜像仓库

    构建私有仓库 启动Docker Registry,使用Docker官方提供的Registry镜像就可以搭建本地私有镜像仓库,具体指令如下. docker run -d -p 5000:5000 --r ...

  10. QOJ 5020. 举办乘凉州喵,举办乘凉州谢谢喵

    QOJ 5020. 举办乘凉州喵,举办乘凉州谢谢喵 飞天数据结构. 思路 设 \(f[u][k]\) 为 \(u\) 子树内距离 \(u\) 小于等于 \(k\) 的点的个数,\(g[u][k]\) ...