2013-12-15 5 views
2

Я хочу прослушать поток событий, а затем условно прекратить прослушивание на основе полученного события.Прекратить прослушивание события из внутреннего прослушивателя событий

Короче говоря, я хотел бы использовать:

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

Это, очевидно, не работает; subscription не существует до тех пор, пока слушатель не будет создан, что приведет к ошибке.

Как это сделать?

ответ

5

Просто объявить подписку, прежде чем подписываться на поток:

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

теперь я чувствую себя глупо. По какой-то причине я подумал, что дротик имеет захват по значению, а не захват по имени (с чем-то интересным, происходящим с петлями). – dhasenan

2

Разделить и победить.

Прежде всего, рассмотрим деталь if (f(event)). Это занимает только первый элемент, который соответствует предикату и выполняет операцию. Есть два способа сделать это:

stream.where((event) => f(event)).take(1).listen((event) => doStuff()); 

Это общий способ делать вещи, и это означает, что мы используем интерфейс потока через все. Другим способ сделать это, что может избежать несколько сложения и операций сравнения, требует включений в будущий интерфейс:

stream.firstWhere((event) => f(event)).then((event) => doStuff()); 

Это обрабатывает только первую часть условия. Как насчет второй части? Мы хотим, чтобы захватить все, пока условие не верно, поэтому мы будем использовать takeWhile:

stream.takeWhile((event) => !f(event)).listen((event) => doOtherStuff()); 

И Боба твой дядя.

Если код по существу одинаковый для обоих слушателей, вы можете разделить его на другую функцию, конечно.

Смежные вопросы