如何使用RxJava2和&amp ;;进行并行多个非阻塞服务请求Retrofit2

时间:2017-09-05 05:44:06

标签: android asynchronous parallel-processing retrofit2 rx-java2

我需要一些帮助来实现使用RxJava2&的并行异步调用。 Retrofit2。 我的要求是;

1)我有多个保险公司(现在我只拿两个),我需要使用该保险公司名称发送多个并行请求。

2)如果其中任何一个发出服务器错误,那么剩下的请求不应该被阻止。

以下是我到现在为止所尝试的内容;

ArrayList<String> arrInsurer = new ArrayList<>();
        arrInsurer.add(AppConstant.HDFC);
        arrInsurer.add(AppConstant.ITGI);

        RequestInterface service = getService(ServiceAPI.CAR_BASE_URL);
        for (String insurerName : arrInsurer) {
            service.viewQuote(Utils.getPrefQuoteId(QuoteListActivity.this), insurerName)
                    .subscribeOn(Schedulers.computation())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<ViewQuoteResDTO>() {
                        @Override
                        public void accept(@NonNull ViewQuoteResDTO viewQuoteResDTO) throws Exception {
                            Log.e("Demo", viewQuoteResDTO.getPremiumData().getIDV()+"");
                             updateList();
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(@NonNull Throwable throwable) throws Exception {
                            Log.e("Demo", throwable.getMessage());
                        }
                    });
        }

private RequestInterface getService(String baseUrl) {      
    Gson gson = new GsonBuilder()
            .setLenient()
            .create();

    return new Retrofit.Builder()
            .baseUrl(baseUrl)                
           .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build().create(RequestInterface.class);

}

现在,仅当两个请求都给出成功响应时,上面的代码才能正常工作。但是当任何请求将响应作为内部服务器错误时,请求的其余部分也会被阻止。

跟踪日志错误,当任何请求给出失败响应时我得到;

E/Demo: HTTP 500 Aww Snap, Some thing happened at server. Please try back again later.
E/Demo: unexpected end of stream on Connection{100.xxx.xxx.xx:portNo, proxy=DIRECT@ hostAddress=/100.xxx.xxx.xx:portNo cipherSuite=none protocol=http/1.1}

如何处理此错误?

1 个答案:

答案 0 :(得分:1)

我想像任何其他与Rx相关的问题,这有多个答案。我会告诉你我在我们的应用程序中使用的并完全解决了这个用例。希望它有所帮助。

简短版本 - 这取决于mergeDelayError。查看here

为什么merge?因为与concat不同,它将并行执行observable。为什么mergeDelayError?它延迟了错误...基本上它将执行每个observable并在一切结束时传递错误。这样可以确保即使出现一个或多个错误,其他错误仍将执行。

你必须小心一些细节。不再保留事件的顺序,这意味着merge运算符可以交错一些可观察的事件(鉴于你以前做过的事情,这应该不是问题)。据我所知,即使多个可观察对象失败,您也只能进行一次onError通话。如果这两个都没问题,那么您可以尝试以下方法:

List<Observable<ViewQuoteResDTO>> observables = new ArrayList<>();
for (String insurerName : arrInsurer) {     
   observables.add(service.viewQuote(
         Utils.getPrefQuoteId(QuoteListActivity.this), insurerName));
}

Observable.mergeDelayError(observables)
          .subscribeOn(Schedulers.computation())
          .observeOn(AndroidSchedulers.mainThread())
          .subscribe(/* subscriber calls if you need them */);

我们的想法是创建您要运行的所有可观察对象,然后使用mergeDelayError来触发它们。