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. 2021年8月国产数据库排行榜:TiDB稳榜首,达梦返前三,Kingbase进十强,各厂商加速布局云生态

    8月份的国产数据库流行度排行榜新鲜出炉.本月共有139个数据库参与了排名. 先来看看排行榜前五名.PingCAP的TiDB分数连续第二个月上涨,总分达到630.21,以136.48的分数差拉开了与第二 ...

  2. excel导⼊功能的实现流程简要描述⼀下?

    当时公司的场景⼤概⼀个excel⽂件⾥就⼏⼗条数据,量⽐较少,和后端商量之后制定了前端主导的⽅ 案,解析的过程放到了浏览器端做,当时是参考了⼀下vue-admin中的现成的⽅案 ⼤概流程是这样的,⼈事 ...

  3. Vue中mixins(混入)的介绍和使用

    为什么引进 mixins 随着项目的开发,组件越来越多 ,这就导致了在各个组件中需要编写功能相同的代码段,重复地定义这些相同的属性和方法,导致代码地冗余,还不利于后期代码的维护 混入mixins 的创 ...

  4. kotlin类与对象——>可见性修饰符

    1.在 Kotlin 中有这四个可⻅性修饰符:private .protected .internal 和public .如果没有显式指定修饰符的话,默认可⻅性是 public . 2.包,函数.属性 ...

  5. 云原生爱好者周刊:Chaos Mesh 升级成为 CNCF 孵化项目

    云原生一周动态要闻: Chaos Mesh 升级成为 CNCF 孵化项目 Zabbix Web Frontend 中发现安全漏洞 2021 年 Rust 调查报告出炉 Sysdig 2022 云原生安 ...

  6. 函数(C语言)

    目录 1. 函数的概念 2. 库函数 2.1 标准库和头文件 2.2 库函数的使用方法 3. 自定义函数 3.1 函数的语法形式 3.2 函数的举例 4. 形参和实参 4.1 实参 4.2 形参 4. ...

  7. npm安装html2canvas依赖报错 npm ERR! Unexpected token < in JSON at position 0 while parsing near '<!DOCTYPE html> npm ERR! <htm...'

    今天安装某个依赖时发现npm ERR! 可我是正常操作啊,也没有升级啥的,咋就安装不了了? npm install --save html2canvas 报错信息如下: npm ERR! Unexpe ...

  8. Kubernetes上安装nacos

    k8s配置 --- apiVersion: apps/v1 kind: Deployment metadata: name: nacos namespace: com spec: selector: ...

  9. 开源 - Ideal库 - 常用时间转换扩展方法(二)

    书接上回,我们继续来分享一些关于时间转换的常用扩展方法. 01.时间转日期时间 TimeOnly 该方式是把TimeOnly类型转为DateTime类型,其中日期部分使用系统当前日期,时间部分则使用T ...

  10. 使用MySQL Shell 8.4.1-LTS 直接将数据复制到 MySQL实例

    在之前的文章中,我谈到了如何使用 MySQL Shell 通过多线程过程来转储和加载数据,以及如何以不同格式导出表数据,然后可以将这些数据导入到新的 MySQL 实例中.这篇文章将讨论我们如何直接将数 ...