Я в основном знаю, как их использовать; например, прослушивание потока OnClick элемента.
Но как вы настраиваете свои собственные потоки?
Я в основном знаю, как их использовать; например, прослушивание потока OnClick элемента.
Но как вы настраиваете свои собственные потоки?
Вот полный рабочий пример:
import 'dart:async';
import 'dart:io';
class Application {
Stream onExit;
Application() {
// Create a stream controller and assign its stream to "onExit".
var controller = new StreamController();
onExit = controller.stream;
// Create some class that uses our stream.
new UserOfStream(this);
// Whenever we exit the application, notify everyone about it first.
controller.add('we are shutting down!');
exit(0);
}
}
class UserOfStream {
UserOfStream(app) {
app.onExit.listen((String message) => print(message));
}
}
main() => new Application();
Вы также можете делать классные вещи, например, проверить наличие подписчиков с controller.hasListener
, или вы можете сообщить об ошибке. Обязательно проверьте документацию API на StreamController
.
Вы можете использовать new StreamController.broadcast()
для разрешения нескольких прослушивателей.
Вот простой способ создания потока (отличный фрагмент для копий-пастеров):
class Something {
StreamController _onExitController = new StreamController.broadcast();
Stream get onExit => _onExitController.stream;
}
Затем класс может просто получить доступ к _onExitController
для управления потоком (например, .add()
).
Я только что создал новую Dart-библиотеку под названием event_stream, чтобы упростить создание настраиваемых событий на ваших классах. Вот пример:
class ClassWithEvents implements NotifyPropertyChanged {
String _someProperty;
final EventStream<PropertyChangedEventArgs> _onPropertyChangedEvent = new EventStream<PropertyChangedEventArgs>();
Stream<PropertyChangedEventArgs> get onPropertyChanged => _onPropertyChangedEvent.stream;
final EventStream _onClosedEvent = new EventStream();
Stream get onClosed => _onClosedEvent.stream;
String get someProperty => _someProperty;
set someProperty(String value) {
_onPropertyChangedEvent.signal(new PropertyChangedEventArgs('someProperty', value));
_someProperty = value;
}
close() {
_onClosedEvent.signal();
}
}
main() {
var c = new ClassWithEvents();
c.onPropertyChanged.listen((PropertyChangedEventArgs<String> args) => print('changed: name=${args.propertyName} value=${args.value}'));
c.onClosed.listen((_) => print('closed'));
c.someProperty = "test";
c.close();
}
В дополнение к StreamController
вы можете создать экземпляр Stream
непосредственно с одним из его названных конструкторов:
Stream.fromFuture()
Возвращает поток, который запускает одно событие (независимо от того, что "будущее" завершает.)
Stream.fromIterable()
Возвращает поток, который преобразует элементы Iterable
в последовательность событий.
Stream.periodic()
Возвращает поток, периодически запускающий вычисляемое событие.
Это очень удобно, так как вы можете написать код, который ожидает использования потока, но у вас есть несколько вариантов того, как передавать события этому классу. Например: Stream.fromIterable()
может использоваться в unit test для запуска известной последовательности событий классу, который в противном случае обычно должен быть передан событиям данных, считанным из файла.