Stream Dart:如何将转换器附加到现有流?

Stream Dart:如何将转换器附加到现有流?,stream,dart,dart-async,Stream,Dart,Dart Async,我正在寻找一种方法,以编程方式将转换器添加到已被侦听的现有流中 例如: Stream number=新的Stream.fromIterable([0,1,2,3]); 数字。听((数字)=>打印(数字)); 现在,为了响应某个UI事件,我想通过添加映射转换器来修改此流,就像我最初编写的: number。其中((number)=>number%2==0); 从现在起,所有现有的侦听器都应该只接收偶数,不会中断。如何做到这一点?我可以想到的一种方法是使用调用另一个函数的函数过滤流: var过滤器

我正在寻找一种方法,以编程方式将转换器添加到已被侦听的现有流中

例如:

Stream number=新的Stream.fromIterable([0,1,2,3]);
数字。听((数字)=>打印(数字));
现在,为了响应某个UI事件,我想通过添加映射转换器来修改此流,就像我最初编写的:

number。其中((number)=>number%2==0);

从现在起,所有现有的侦听器都应该只接收偶数,不会中断。如何做到这一点?

我可以想到的一种方法是使用调用另一个函数的函数过滤
流:

var过滤器=(n)=>true;
流编号=新字符串.fromIterable([0,1,2,3])。其中((n)=>过滤器(n));
然后,当您要更改筛选时:

filter=(n)=>n%2==0;
一个具体的例子:

导入'dart:async';
main(){
变量过滤器=(n)=>真;
流编号=新流。周期性(新持续时间(秒:1),(n)=>n)
。式中((n)=>过滤器(n));
数字。听((n)=>打印(n));
新的未来。延迟(新的持续时间(秒:4))。然后((){
筛选器=(n)=>n%2==0;
});
}
这将打印:

0
1.
2.
3.
4.
6.
8.
10
12

以此类推,仅限偶数,4秒后。

与其像“如何将转换器动态插入流”那样思考,不如像“如何动态控制已注入的转换器”那样思考

下面是一个使用
StreamTransformer
的示例:

var onlySendEvenNumbers=false;//由某个UI事件处理程序控制
var originalStream=makeStreamOfStuff();
originalStream=originalStream.transform(新的StreamTransformer.fromHandlers(
handleData:(int值,EventSink){
如果(仅限登录编号){
如果(值为isEven){
增加(价值);
}
}否则{
增加(价值);
}
}));
原始流。听(打印);//听一些像平常一样的事情

rxdart的
组合测试2
怎么样

它组合两个流,并在每次更改两个流时发射

您可以使用开关类在条件下打开/关闭

classxsbloc{
Api _Api=Api();
行为主体_xs=行为主体();
行为主体切换器=
BehaviorSubject.seed(Switcher(false,[]);
XsBloc(){
可观察的,可观察的(
_api.xs(),_切换器,(xs,s){
如果(s.isOn==真){
返回xs.where((x)=>s.conditions.contains(x.id)).toList();
}否则{
返回xs;
}
}).听((x)=>xs.add(x));
}
流get xs=>xs;
ValueObservable获取切换器=>
_切换器流;
函数(Switcher)get setSwitcher=>\u Switcher.sink.add;
}
类切换器{
最终目标;
最终清单条件;
切换开关(此.isOn,此.conditions);
}
var bloc=XsBloc();
集合开关(真,['A','B']);
集团设置开关(假,[]);
集团设置开关(真,[]);

您不需要将
transform
返回的值赋给
originalStream
?或者,
转换
转换到位了吗?我同意。不能在流订阅与其侦听器之间插入代码。订阅(它是流的活动部分,就像iterable的迭代器一样)将其值直接发送给侦听器,而这不在您的掌握之中。在允许某人监听之前,您需要添加过滤功能,然后您可以动态更改过滤器的功能-因为它是您的过滤器,而不是侦听器的。这真的很像对流通信的“中间人”攻击——你必须从一开始就在那里。这就是我目前使用的,一个占位符函数,它本身有一组谓词(映射器也可以这样做)。这行得通,但似乎不雅观,也不能作曲。假设我想添加一个中间过滤器,我必须预先考虑它,并在编写代码时插入一个占位符。