如何在rxjava中等待改进响应

时间:2018-05-03 14:30:28

标签: android retrofit2 rx-java2

我使用retrofit2和rxjava扩展名。

我有一个REST API网址列表,并希望这样做:

    每个
    • 检查相应的文件是否存在本地
    • 如果是:调用API并存储响应或HTTP错误
    • 如果不是:存储自定义错误
  • 返回这些结果列表

我的问题是:apply在收到服务器响应之前返回(带有空RequestResult)。我想,我理解为什么,但我不知道如何修复它,因为我需要返回一个RequestResult而不是Retrofit可观察的。

如何解决这个问题?

这是我的代码:

@GET
Observable<Response<ResponseBody>> enroll(@Url String url);


class RequestResult {
    CustomException error;
    Response<ResponseBody> response;
}

Observable<ClassOfListItem> observable = Observable.fromIterable(listOfItems);

observable
    .flatMap(new Function<ClassOfListItem, ObservableSource<RequestResult>>() {

        @Override
        public ObservableSource<RequestResult> apply(ClassOfListItem listItem) throws Exception {

            RequestResult requestResult = new RequestResult();
            if (fileExists(listItem.url))   {
                Observable<Response<ResponseBody>> callObservable = restAPI.enroll(listItem.url)
                    .subscribeOn(Schedulers.io());

                callObservable
                    .subscribe(new DisposableObserver<Response<ResponseBody>>() {
                        @Override
                        public void onNext(Response<ResponseBody> responseBodyResponse) {
                            onPremiseEnrollmentResult.response = responseBodyResponse;
                        }
                        @Override
                        public void onError(Throwable e) {
                            onPremiseEnrollmentResult.error = new CustomException(e);
                        }
                        @Override
                        public void onComplete() {
                        }
                    });
            }
            else {
                requestResult.error = new CustomException("file not found");
            }
            return Observable.just(requestResult);
        }
    }
    .toList()
    .observerOn(AndroidScheduler.mainThread())
    .subscribe(new DisposableSingleObserver<List<RequestResult>>() {
        @Override
        public void onError(Throwable e) {
            Log.d("onError", e.getMessage());
        }
        @Override
        public void onSuccess(List<RequestResult> requestResults) {
            // parse results
        }
    }
 )

2 个答案:

答案 0 :(得分:1)

flatMap()运算符允许您将一个observable转换为另一个observable。你的apply()里面有一个嵌套的观察者链,它不是观察者链的一部分,所以它是空的,因为它还没有完成。

要解决此问题,当文件存在时,返回observable。

observable
  .flatMap(new Function<ClassOfListItem, ObservableSource<RequestResult>>() {
    @Override
    public ObservableSource<RequestResult> apply(ClassOfListItem listItem) throws Exception {
        RequestResult requestResult = new RequestResult();
        if (fileExists(listItem.url))   {
            return restAPI.enroll(listItem.url)
                .subscribeOn(Schedulers.io());
        }
        return Observable.error( new CustomException("file not found") );
    }
}
.toList()
.observerOn(AndroidScheduler.mainThread())
.subscribe(new DisposableSingleObserver<List<RequestResult>>() {
    @Override
    public void onError(Throwable e) {

        Log.d("onError", e.getMessage());
    }

    @Override
    public void onSuccess(List<RequestResult> requestResults) {
        // parse results
    }
}

如果您需要将错误和成功捕获到列表中,则可以添加map()运算符以围绕响应包裹RequestResult,并onErrorResumeNext()包裹RequestResult toList()运算符之前的错误。

答案 1 :(得分:1)

如果你在后台线程上进行api调用,那么你可以做的是同步调用它....在你的情况下你的改装api方法将改为以下

Call<Response<ResponseBody>> enroll(@Url String url);

您可以通过致电restAPI.enroll(listItem.url).execute()

来调用