Подтвердить что ты не робот

Как вы создаете Stream в Dart?

Я в основном знаю, как их использовать; например, прослушивание потока OnClick элемента.

Но как вы настраиваете свои собственные потоки?

4b9b3361

Ответ 1

Простой пример

Вот полный рабочий пример:

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()).

Ответ 2

Я только что создал новую 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();
}

Ответ 3

В дополнение к StreamController вы можете создать экземпляр Stream непосредственно с одним из его названных конструкторов:

  • Stream.fromFuture() Возвращает поток, который запускает одно событие (независимо от того, что "будущее" завершает.)

  • Stream.fromIterable() Возвращает поток, который преобразует элементы Iterable в последовательность событий.

  • Stream.periodic() Возвращает поток, периодически запускающий вычисляемое событие.

Это очень удобно, так как вы можете написать код, который ожидает использования потока, но у вас есть несколько вариантов того, как передавать события этому классу. Например: Stream.fromIterable() может использоваться в unit test для запуска известной последовательности событий классу, который в противном случае обычно должен быть передан событиям данных, считанным из файла.