我正在尝试通过使用async gets来提高查询couchbase视图的性能。 我已经阅读了他们关于正确方法的文档,它类似于:
Cluster cluster = CouchbaseCluster.create();
Bucket bucket = cluster.openBucket();
List<JsonDocument> foundDocs = Observable
.just("key1", "key2", "key3", "key4", "key5")
.flatMap(new Func1<String, Observable<JsonDocument>>() {
@Override
public Observable<JsonDocument> call(String id) {
return bucket.async().get(id);
}
})
.toList()
.toBlocking()
.single();
哪个效果很好而且速度很快,但由于我依赖于结果的顺序,似乎我需要做一些额外的工作来保持结果的有序性。 在上面的示例中,JsonDocument列表包含所有5个文档,但是顺序随着调用而变化。 有没有任何优雅的方法来使用JavaRx功能或couchbase Java SDK功能来订购结果?
我能想到的唯一解决方案是将结果保存到HashMap中,然后使用此HashMap将原始的id列表转换为JsonDocuments的有序列表。
答案 0 :(得分:2)
您可以使用:
代替flatMap
concatMap
:将保留顺序,但实际上等待每个内部GET
完成后再触发下一个(可以恢复顺序执行,性能较差)concatMapEager
:将立即订阅内部Observable(因此触发内部GET
)。通过缓冲无序到达的响应来维持顺序,直到它们可以在序列中的正确索引处重放。在订购和性能方面,两全其美。答案 1 :(得分:0)
我会使用Zip运算符来连接所有可观察对象,然后一旦完成将文档结果添加到列表中
@Test
public void zipObservables() {
Observable<String> oKey1 = Observable.just("key1").doOnNext(getDocument());
Observable<String> oKey2 = Observable.just("key2").doOnNext(getDocument());
Observable<String> oKey3 = Observable.just("key3").doOnNext(getDocument());
Observable<String> oKey4 = Observable.just("key4").doOnNext(getDocument());
List<Observable<String>> observables = Arrays.asList(oKey1,oKey2,oKey3,oKey4);
List<Object> foundDocs = Observable.zip(observables, Arrays::asList)
.toBlocking()
.single();
}
private Action1<String> getDocument() {
return id -> bucket.async().get(id);
}
您可以在此处查看更多Zip示例https://github.com/politrons/reactive/blob/master/src/test/java/rx/observables/combining/ObservableZip.java