停止监听内部事件监听器的事件

14

我想监听一个事件流,然后根据收到的事件有条件地停止监听。

简而言之,我想使用:

var subscription = stream.listen((event) {
    if (f(event)) {
        doStuff();
        subscription.cancel();
    } else {
        doOtherStuff();
    }
});

显然这样做不起作用; subscription 直到监听器被创建后才存在,导致出现错误。

我该怎么做?

2个回答

27

在订阅流之前先声明订阅:

var subscription;
subscription = stream.listen((event) {
  if (f(event)) {
    doStuff();
    subscription.cancel();
  } else {
    doOtherStuff();
  }
});

1
现在我感觉很傻。我错误地认为Dart采用按值捕获而不是按名称捕获(在循环中发生了一些有趣的事情)。 - dhasenan

8

分而治之。

首先,让我们考虑 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());

而你的问题迎刃而解。

如果这两个监听器的代码本质相同,当然可以将其分离到另一个函数中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接