Rx java 如何";“合并”;运行时的可观测值?

Rx java 如何";“合并”;运行时的可观测值?,rx-java,Rx Java,我的用例是视图组中的单击侦听器: 每个视图发布一个可观察的冷API 视图组管理一组视图,并提供从子视图发出单击的可观察的API 我希望每个子视图在添加到复合可观察对象时都被订阅,但前提是复合对象有订阅。如果没有,则应仅在订阅组合时订阅子项 到目前为止,我的解决方案是: PublishSubject<ViewClick> composite; Map<View, Subscription> subscriptions; void addSource(View view

我的用例是视图组中的单击侦听器:

  • 每个
    视图
    发布一个可观察的冷
    API

  • 视图组管理一组视图,并提供从子视图发出单击的
    可观察的
    API

我希望每个子视图在添加到复合可观察对象时都被订阅,但前提是复合对象有订阅。如果没有,则应仅在订阅组合时订阅子项

到目前为止,我的解决方案是:

PublishSubject<ViewClick> composite;
Map<View, Subscription> subscriptions;

void addSource(View view, Observable<Click> clicks) {
    Subscription s = clicks.map(click -> new ViewClick(view, click)
     .subscribe(composite::onNext);
    subscriptions.put(view, s);
}

void removeSource(View v) {
    Subscription s = subscriptions.get(v);  
    s.unsubscribe;
    subscriptions.remove(v);  
}

Observable<ViewClick> compositeClicks() {
    return composite;
}
出版主题组合;
地图订阅;
void addSource(视图、可观察到的点击){
订阅s=单击.map(单击->新建视图单击(查看,单击)
.订阅(复合::onNext);
订阅。放置(视图,s);
}
void removeSource(视图v){
订阅s=订阅。获取(v);
s、 退订;
删除(v);
}
可观测的复合icks(){
收益组合;
}
然而,这意味着
点击
观察对象不再是冷的,因为无论是否订阅了
复合点击
,它们都被订阅了

有更好的方法吗?

您需要一个特殊的“温暖”主题,例如
BufferUntilSubscriber
,它保留源观测值,直到单个消费者订阅。不幸的是,该类不是官方API的一部分,但是,2.0将有一个官方的
UnicastSubject
,用于同样的目的:

UnicastSubject<Observable<Integer>> inputs = UnicastSubject.create();

Observable<String> p = inputs
        .flatMap(v -> v.map(u -> u.toString()))
        .publish()
        .autoConnect()
        ;

inputs.onNext(Observable.just(1)
    .doOnSubscribe(s -> System.out.println("Subscribed to 1")));
inputs.onNext(Observable.just(2)
    .doOnSubscribe(s -> System.out.println("Subscribed to 2")));
inputs.onNext(Observable.just(3)
    .doOnSubscribe(s -> System.out.println("Subscribed to 3")));

System.out.println("Subscribing to p");

p.subscribe(System.out::println);
UnicastSubject输入=UnicastSubject.create();
可观测p=输入
.flatMap(v->v.map(u->u.toString())
.publish()
.自动连接()
;
inputs.onNext(可观察到的。仅(1)
.doOnSubscribe(s->System.out.println(“订阅1”);
inputs.onNext(可观察到的)just(2)
.doOnSubscribe(s->System.out.println(“订阅2”);
inputs.onNext(可观察到的)just(3)
.doOnSubscribe(s->System.out.println(“订阅3”);
System.out.println(“订阅p”);
p、 订阅(System.out::println);

您的困难来自addSource/removeSource不是反应性的,如果您将它们放入Rx流中,它们就会消失

有几种方法可以做到这一点:

  • IObservable
    其中内部可观测对象在激活/添加时将有一个
    onNext
    ,在移除时将
    onComplete
  • IObservable
    x2(一个用于添加,一个用于删除)
  • IObservable
    (具有添加/删除种类+视图实例的元组)
(假设您的点击流可以从视图中提取,否则您需要为激活部分提供一个元组视图+点击流来代替视图)

下面是使用上面的#2实现流的方式,但所有方法都可以工作:

Subject<View> add,remove;

clicks = add.flatMap(view -> getClickObservable(view).takeUntil(remove.where(v => v == view)))
主题添加、删除;
clicks=add.flatMap(视图->getClickObservable(视图).takeUntil(remove.where(v=>v==view)))