如何为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);
}
}
答案 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);