使用defaultValue作为Observable的BehaviorSubject

时间:2015-06-08 13:55:07

标签: java rx-java

如何为BehaviourSubject提供Observable的默认值?

所以而不是:

// observer will receive the "default", "zero", "one"
BehaviorSubject<Object> subject = BehaviorSubject.create("default");
subject.subscribe(observer);
subject.onNext("zero");
subject.onNext("one");

// observer2 will receive the "one", "two", "three"
subject.subscribe(observer2);
subject.onNext("two");
subject.onNext("three");

可以这样做:

Observable<Object> defaultValueObservable = Observable.defer(new Func0<Observable<Object>>() {
@Override public Observable<Object> call() {
    // simulate blocking work
    return Observable.just("blocking-default");
   }
})

// observer will receive the "blocking-default", "zero", "one"
BehaviorSubject<Object> subject = BehaviorSubject.create(defaultValueObservable.first());
subject.subscribe(observer);
subject.onNext("zero");
subject.onNext("one");

// observer2 will receive the "one", "two", "three"
subject.subscribe(observer2);
subject.onNext("two");
subject.onNext("three");

我明白,第一个观察者会等待计算默认值。我付出这个代价我没事。

基本上,我想要一个内存存储库。我目前的实施理念:

public class Repository<T> {
    private final BehaviorSubject<T> subject;

    public Repository() {
        subject = BehaviorSubject.create();
    }

    public Observable<T> get() {
        assertUiThread();
        Observable<T> observable = subject.asObservable();
        if (subject.hasValue()) {
            return observable;
        } else {
            return observable.startWith(Observable.defer(new Func0<Observable<T>>() {
                @Override public Observable<T> call() {
                    T t = getTfromBlockingSource();
                    return Observable.just(t);
                }
            }));
        }
    }

    public void update(T t) {
        assertUiThread();
        subject.onNext(t);
    }
}

1 个答案:

答案 0 :(得分:1)

我不确定我是否了解您的用例,但我没有原始Object,而是BehaviorSubject<Observable<Object>>现在可以生成其第一个值以及任何后续“原始”值现在可以通过just()包裹。然后,订阅者可以.onBackpressureBuffer().concatMap(v -> v)按顺序恢复序列。

BehaviorSubject<Observable<Object>> hiddenSubject = BehaviorSubject.create(
    Observable.defer(() -> Observable.just("default")));
Subject<Observable<Object>, Observable<Object>> subject = 
    hiddenSubject.toSerialized();

Observable<Object> output = subject.onBackpressureBuffer().concatMap(v -> v);

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

subject.onNext(Observable.just("one"));
subject.onNext(Observable.just("two"));

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