RxJava是一个可观察的,多个订阅者,一个执行

时间:2016-05-04 10:30:08

标签: asynchronous rx-java reactive-programming

我从长时间运行的操作+回调中创建一个Observable:

public Observable<API> login(){
    return Observable.create(new Observable.OnSubscribe<API>() {
        @Override
        public void call(final Subscriber<? super API> subscriber) {
            API.login(new SimpleLoginListener() {
                @Override
                public void onLoginSuccess(String token) {
                    subscriber.onNext(API.from(token));
                    subscriber.onCompleted();
                }
                @Override
                public void onLoginFailed(String reason) {
                    subscriber.onNext(API.error());
                    subscriber.onCompleted();
                }
            });
        }
    })
}

成功登录的api是多个其他操作的前提条件,例如api.getX()api.getY()所以我认为我可以将这些操作链接到RxJava和flatMap这样(简化) ):login().getX()login().getY()

我现在最大的问题是,我无法控制执行login(callback)的时间。但是,我希望能够重用所有呼叫的登录结果。

这意味着:包裹的login(callback)来电应该只执行一次。然后,结果应该用于所有后续调用。

似乎结果类似于聚合订阅者的队列,然后共享第一次执行的结果。

实现这一目标的最佳方法是什么?我错过了一个更简单的选择吗?

我尝试了来自this question的代码并使用cache(), share(), publish(), refCount()等进行了体验,但是当我为所有提到的运算符执行此操作时,包装函数被称为 3x

apiWrapper.getX();
apiWrapper.getX();
apiWrapper.getY();

是否有类似autoConnect(time window)的内容聚合了多个连续订阅者?

2 个答案:

答案 0 :(得分:1)

应用cache()应确保只调用一次登录。

public Observable<API> login() {
    return Observable.create(s -> {
        API.login(new SimpleLoginListener() {
            @Override
            public void onLoginSuccess(String token) {
                s.setProducer(new SingleProducer<>(s, API.from(token)));
            }
            @Override
            public void onLoginFailed(String reason) {
                s.setProducer(new SingleProducer<>(s, API.error()));
            }
        });
   }).cache();
}

如果出于某种原因想要“清除”缓存,可以执行以下操作:

AtomicReference<Observable<API>> loginCache = new AtomicReference<>(login());

public Observable<API> cachedLogin() {
    return Observable.defer(() -> loginCache.get());
}

public void clearLoginCache() {
    loginCache.set(login());
}

答案 1 :(得分:0)

好的我觉得我在我的方法中发现了一个主要问题: Observable.create()是一种工厂方法,所以即使每个单一的observable都按照意图工作,我创建了很多。避免此错误的一种方法是创建单个实例:

if(instance==null){ instance = Observable.create(...) }
return instance
相关问题