繁体   English   中英

如何在rxjava中等待改造响应

[英]How to wait for retrofit response in rxjava

我使用带有rxjava扩展名的retrofit2。

我有一个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
        }
    }
 )

flatMap()运算符使您可以将一个可观察对象转换为另一个可观察对象。 您的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
    }
}

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

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

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

并且可以通过调用restAPI.enroll(listItem.url).execute()进行调用

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM