有条件的可观察链

时间:2016-07-27 13:54:37

标签: android rx-java retrofit2 reactivex

我想通过多个REST API异步检索数据。我在Android上使用Retrofit和rxJava扩展,即我通过订阅Observable来执行任何GET请求。

正如我所说,我有多个源API,所以当第一个源没有产生所需的结果时,我想尝试下一个,如果也失败了,再次尝试下一个,依此类推,直到所有来源都被查询或结果被发现。

我正在努力将这种方法转化为正确使用Observable,因为我不知道哪些运算符可以实现这种行为,并且还有一些限制要遵守:

  • 找到结果后,不应查询剩余的API(如果有)
  • 其他组件依赖于查询的结果,我希望它们在启动请求时获取Observable,因此Observable可以通知它们请求的完成
  • 我需要保留对前面提到的Observable的引用,因为在完成之前可能会多次发出相同的请求,在这种情况下,我只在第一次需要它时启动它,后续请求只获得Observable通知请求完成时

我开始只使用一个API进行查询,并将以下内容用于请求和后续依赖组件的通知:

private Observable<String> loadData(int jobId) {

    final ConnectableObservable<String> result = Async
            .fromCallable(() -> getResult(jobId))
            .publish();

    getRestRequest()
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(
                    dataHolder -> {
                        if (dataHolder.getData() != null && !dataHolder.getData().isEmpty()) {
                            saveData(dataHolder.getData());
                        } else {
                            markNotFound(dataHolder);
                        }
                    },
                    error -> currentJobs.remove(jobId),
                    () -> {
                        currentJobs.remove(jobId);
                        result.connect();
                    });

    return result;
}

此代码仅在第一个请求时被调用,返回的Observable结果将保存在currentJobs中,后续请求只会在不再触发请求的情况下获取Observable。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

假设每次订阅时都有一组可重新连接的可观察对象:

List<Observable<Result>> suppliers = ...

然后你只需要做逻辑:

Observable<Result> results = Observable
          .from(suppliers)
          .concatMap(supplier -> supplier)
          .takeFirst(result -> isAcceptable(result))
          .cache()

答案 1 :(得分:0)

使用.onErrorResumeNext,并假设每个服务可观察对象可能返回0或1个元素,如果没有元素被发出则使用first发出错误:

Observable<T> a, b, c;
...
a.first().onErrorResumeNext(t -> b.first())
 .onErrorResumeNext(t -> c.first())
 .onErrorResumeNext(t -> d.first())
 ...