Как сбросить BehaviorSubject

У меня есть BehaviorSubject что я хотел бы сбросить-под этим я имею в виду, что я хочу, чтобы последнее значение не было доступно, как если бы оно было только что создано.

Я не вижу API для этого, но я предполагаю, что есть другой способ достичь того же результата?

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

4 ответов


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

public static final Object EMPTY = new Object();

BehaviorSubject<Object> subject = BehaviorSubject.createDefault(EMPTY);

Observable<YourType> obs = subject.filter(v -> v != EMPTY).cast(YourType.class);

obs.subscribe(System.out::println);

// send normal data
subject.onNext(1);
subject.onNext(2);

// clear the subject
subject.onNext(EMPTY);

// this should not print anything
obs.subscribe(System.out::println);

другой метод переключения значения наблюдаемого включения и выключения-использовать switchMap() для переключения между фактическим наблюдаемым и пустым.

предположим, у вас есть объект manager, и он имеет наблюдаемый, который показывает его состояние. Затем:

subjectObservable = manager.getStateObservable()
  .switchMap( state -> state == ON ? subject : Observable.never() );

будет излучать только значения в то время как manager находится в ON государство.


Я узнаю лучшее лучшее решение для некоторых случаев и это: тема.skiplast (1) он может работать, чтобы "очистить" последнюю позицию в потоке, которая сохраняется из-за BehaviorSubject "behavior"


проблема с ответом @akarnokd заключается в том, что.cast prevent YourType не является интерфейсом или общим типом, таким как List<String>.

другой вариант-фильтровать логическое поле, которое можно включать и выключать.

    private BehaviorSubject<PandoraApp> subject = BehaviorSubject.create();
    private boolean enabled = true;

    Observable<PandoraApp> observable = subject.filter(v -> enabled);

Если методы вызываются в разных потоках, вы можете использовать AtomicBoolean для флага фильтра.