我从长时间运行的操作+回调中创建一个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)
的内容聚合了多个连续订阅者?
答案 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