代码之家  ›  专栏  ›  技术社区  ›  CaHa

如何在rxjava中等待改装响应

  •  1
  • CaHa  · 技术社区  · 6 年前

    我使用带有rxjava扩展的Reform2。

    我有一个REST API URL列表,希望执行以下操作:

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

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

    如何解决这个问题?

    这是我的代码:

    @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 回复  |  直到 6 年前
        1
  •  1
  •   Bob Dalgleish Denis K.    6 年前

    这个 flatMap() 运算符允许您将一个可观察对象转换为不同的可观察对象。您的内部有一个嵌套的观察者链 apply() 它不是观察者链的一部分,因此它将为空,因为它尚未完成。

    要解决这个问题,当文件存在时,返回可观察的。

    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() 包裹 请求结果 toList() 操作人员

        2
  •  1
  •   John O'Reilly    6 年前

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

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

    你可以通过调用 restAPI.enroll(listItem.url).execute()