FutureBuilder是结束的时候【ConnectionState.done】获得error或者data
StreamBuilder是在过程中【ConnectionState.active】获得error或者data
//创建数据流
final controller = StreamController();
//broadcast可以被多方监听 但是没有缓存,如果添加延时,就会获取不到值
// final controller = StreamController.broadcast();
@override
void initState() {
//添加事件 可以添加任意类型
controller.sink.add(99);
controller.sink.add('啦啦');
//监听数据流
// controller.stream.listen((event) {
// print('$event');
// });
super.initState();
}
@override
void dispose() {
controller.close();
super.dispose();
}
因为要用streamBuilder监听,所以这里的代码把监听事件注释了,如果要多方监听,就需要给StreamController添加广播.broadcast();
广播的确定是无法缓存数据,如果有延时效果之类的,数据不会保存,他只是作为一个通知广播。
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Future学习'),
),
body: Column(
children: [
TextButton(
onPressed: () {
controller.sink.addError('errorMsg');
},
child: Text('添加错误事件')),
StreamBuilder(
//map可以统一处理下数据
//where添加条件 只返回int数据
//distinct 去重
stream: controller.stream
.map((event) => event * 2)
.where((event) => event is int)
.distinct(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
break;
case ConnectionState.waiting:
break;
case ConnectionState.active:
// TODO: 活跃的数据流,随时会产生新的数据和错误,关闭后【done】就不会产生任意数据和错误
//获得error或者data
var str = snapshot.hasError ? snapshot.error : snapshot.data;
return Text('ACTIVE:$str');
break;
case ConnectionState.done:
return Text('DONE:数据流已关闭');
}
return CircularProgressIndicator();
},
),
],
),
);
}
map=》统一处理数据。
where=》添加筛选条件,符合条件才会通知builder重绘。
distinct=》去重,上个事件和本事件重复,就不会通知builder重绘。
stream更适合读取文件之类的实际操作。
关于async和async*
可以理解为用法一样,不过async返回的是future,async*返回的是stream