我想听一个事件流,然后根据收到的事件有条件地停止收听。
简而言之,我想使用:
var subscription = stream.listen((event) {
if (f(event)) {
doStuff();
subscription.cancel();
} else {
doOtherStuff();
}
});
这显然不起作用;在创建监听器之前,subscription
不存在,导致错误。
我该怎么做?
答案 0 :(得分:6)
在订阅流之前声明订阅:
var subscription;
subscription = stream.listen((event) {
if (f(event)) {
doStuff();
subscription.cancel();
} else {
doOtherStuff();
}
});
答案 1 :(得分:3)
分而治之。
首先,让我们考虑if (f(event))
部分。这只需要与谓词匹配的第一个项目并执行操作。有两种方法可以做到这一点:
stream.where((event) => f(event)).take(1).listen((event) => doStuff());
这是通用的做事方式,这意味着我们一直使用Stream接口。另一种方法,可以避免一些添加和比较操作,需要切换到Future接口:
stream.firstWhere((event) => f(event)).then((event) => doStuff());
只处理条件的第一部分。那第二部分呢?我们希望在条件成立之前抓住所有内容,因此我们将使用takeWhile
:
stream.takeWhile((event) => !f(event)).listen((event) => doOtherStuff());
鲍勃是你的叔叔。
如果两个侦听器的代码基本相同,那么当然可以将它分成另一个函数。