我正在从多个来源加载数据并缓存它们。
我的工作如下:
我想要的是:
一个简单的例子如下:
mObservable1 = Observable
.concat(mObservable1Cached, mObservable1)
.first();
如何组合许多缓存而不是上面示例中的缓存可观察量只有1?这是我的想法,但这不起作用,因为只要两个observable中的一个有缓存数据,它就会传播结果......
mObservable1And2 = Observable
.concat(
Observable.merge(mObservable1Cached, mObservable2Cached),
Observable.merge(mObservable1, mObservable2)
)
.first();
Observables示例
缓存数据可观察
mObservable1Cached = Observable.create(new Observable.OnSubscribe<List<Data>>() {
@Override
public void call(Subscriber<? super List<Data>> subscriber) {
subscriber.onNext(mData1Cached);
subscriber.onCompleted();
}
})
.subscribeOn(HandlerScheduler.from(mBackgroundHandler))
.observeOn(AndroidSchedulers.mainThread());
加载数据可观察
mObservable1 = Observable.create(new Observable.OnSubscribe<List<Data>>() {
@Override
public void call(Subscriber<? super List<Data>> subscriber) {
subscriber.onNext(...load data...);
subscriber.onCompleted();
}
})
.doOnNext(new Action1<List<Data>>() {
@Override
public void call(List<Data> data) {
mData1Cached = data;
}
})
.subscribeOn(HandlerScheduler.from(mBackgroundHandler))
.observeOn(AndroidSchedulers.mainThread());
答案 0 :(得分:0)
这与rx模式类似,如何获得表单提交。使用包含2个表单字段的UI时,只需要在两个表单都存在时启用提交按钮。 RxJava允许您使用combineLatest运算符执行此操作。每当一个observable发出一个项目时,它将与另一个发射的observable中的最后一个发射项目组合在一起。如果到目前为止只发出一个observable,它会等待另一个observable发出,然后传递这两个值。
CombineLatest是我对如何使其发挥作用的猜测。
答案 1 :(得分:0)
zip()可以解决问题。
这是完整的(java8)解决方案。 如果你受到java7的限制,重构的重要性就是认为它会更加冗长。 使用zip还可以处理任意数量的源(不仅仅是固定数量)。
mail
输出:
//Dummy data
static class Data {
static Map<String, AtomicInteger> dataVersion = new ConcurrentHashMap<>();
int sourceId;
int itemId;
int version;
Data(int sourceId, int itemId) {
this.sourceId = sourceId;
this.itemId = itemId;
//for testing purpose we going to track how many items created for each source/item pair
//we always expect one
AtomicInteger versionCounter = dataVersion.computeIfAbsent(sourceId + "." + itemId, key->new AtomicInteger());
this.version = versionCounter.incrementAndGet();
}
public String toString() {
return sourceId + "." + itemId + "; version: " + version;
}
};
//data cache (per source)
ConcurrentMap<Integer, List<Data>> sourceCache = new ConcurrentHashMap<>();
//data loader
List<Data> loadData(int sourceId) {
return Arrays.asList(new Data(sourceId,1), new Data(sourceId,2), new Data(sourceId,3));
}
//source observable factory method
Observable<List<Data>> getSource(int sourceId) {
return Observable.<List<Data>>create(subscriber->{
subscriber.onNext(sourceCache.computeIfAbsent(sourceId, key->loadData(key)));
subscriber.onCompleted();
});
}
public void stackOverflow33296442() {
Observable<List<Data>> result = Observable.zip(getSource(1), getSource(2), (src1,src2)->Arrays.asList(src1,src2))
.concatMap(listOfLists->Observable.from(listOfLists));
//Test
Iterator<List<Data>> iter1 = result.toBlocking().toIterable().iterator();
while (iter1.hasNext()) {
List<Data> next = iter1.next();
System.out.println("data: " + next);
for (Data data : next) {
assert 1 == data.version;
}
}
Iterator<List<Data>> iter2 = result.toBlocking().toIterable().iterator();
while (iter2.hasNext()) {
List<Data> next = iter2.next();
System.out.println("data: " + next);
for (Data data : next) {
assert 1 == data.version;
}
}
}
答案 2 :(得分:0)
你要求阻塞直到完成连接的可观察量,这可以像这样实现:
onClick()