本文基于以下文章翻译整合:
https://medium.com/@ayushpguptaapg/using-streams-in-flutter-62fed41662e4
https://www.woolha.com/tutorials/flutter-using-streamcontroller-and-streamsubscription
Stream与RxJava的Observable类似,就像它的名字,它是一系列的异步事件。你可以在一个地方定义一个Stream,在其他地方向这个Stream添加数据或者监听它数据的变化,以此来更新你的Widget。
首先,开始之前,别忘记导包:
import 'dart:async';
1、创建一个简单的Stream
使用Stream.fromFuture来创建一个Stream:
@override
void initState() {
super.initState();
print("Creating a sample stream...");
Stream<String> stream = new Stream.fromFuture(getData());
print("Created the stream");
stream.listen((data) {
print("DataReceived: "+data);
}, onDone: () {
print("Task Done");
}, onError: (error) {
print("Some Error");
});
print("code controller is here");
}
Future<String> getData() async {
await Future.delayed(Duration(seconds: 5)); //Mock delay
print("Fetched Data");
return "This a test data";
}
注意:‘code controller is here’在Stream发射数据之前就已打印,说明操作是异步的。
代码分解:首先我们创建了一个Stream,它从getData()函数中获取数据,getData()这个函数在5秒延迟之后返回一个字符串。然后,我们通过.listen()方法监听Stream的数据,listen方法包含接收数据处理,和两个onDone onError 可选参数,onDone意味着流已经完成,一旦进入到这个回调,流会自动关闭。
当任务完成后,应该关闭Stream(流),否则当你的App很复杂或者你有很多Stream时,性能会有损失。
2、使用SteamController创建一个Stream
SteamController构造函数有以下几个参数:
参数 | 类型 |
---|---|
onListen | Function |
onPause | Function |
onResume | Function |
onCancel | Function |
sync | boolean (default: false) |
listen方法有以下几个参数:
参数 | 类型 |
---|---|
onListen (必须提供 ) | Function |
onDone | Function |
onError | Function |
cancelOnError | bool |
StreamController<String> streamController = new StreamController();
@override
void initState() {
super.initState();
print("Creating a StreamController...");
streamController.stream.listen((data) {
print("DataReceived: " + data);
}, onDone: () {
print("Task Done");
}, onError: (error) {
print("Some Error");
});
streamController.add("This a test data");//通过add发送数据
streamController.addError(new Exception('An exception'));//可以通过addError发出异常
print("code controller is here");
}
@override
void dispose() {
streamController.close(); //不再需要时,Streams必须关闭
super.dispose();
}
注意这里onDone()方法未被调用,因为Stream还活着,它没有被关闭。这就是为什么要关闭Stream(本例在dispose()方法中关闭)避免内存泄漏问题。
3、StreamSubscription
listen() 方法返回StreamSubscription:
subscription向listener提供事件,并持有用于处理这些事件的回调。subscription也可用于取消订阅事件,或暂时暂停流中的事件。
subscription.pause(Future.delayed(const Duration(seconds: 5)));
需要牢记的是:当订阅不需要时别忘记取消订阅。
4、Broadcast Streams
Dart中有两种类型的流:单订阅关系的流( single-subscription streams )和广播流(broadcast streams)。他们的主要区别是广播流可以有多个订阅者。
StreamController<String> streamController =
new StreamController.broadcast(); //Add .broadcast here
@override
void initState() {
super.initState();
print("Creating a StreamController...");
//First subscription
streamController.stream.listen((data) {
print("DataReceived1: " + data);
}, onDone: () {
print("Task Done1");
}, onError: (error) {
print("Some Error1");
});
//Second subscription
streamController.stream.listen((data) {
print("DataReceived2: " + data);
}, onDone: () {
print("Task Done2");
}, onError: (error) {
print("Some Error2");
});
streamController.add("This a test data");
print("code controller is here");
}