完成所有调用后,从列表和调用方法中进行n次异步调用

时间:2018-10-09 19:26:59

标签: android asynchronous retrofit2 reactive-programming rx-java2

我进行了n次异步调用(n是数组列表的大小,并且索引作为整数参数传递给调用),并且希望在所有调用完成后调用一个方法。我在下面实现了以下代码。我用一个计数器知道所有调用都已完成。它正在工作,但是我知道可以用更高效,更优雅的方式来完成它。

int n = mUserUrls.getM3u().size();

counter = n;

Observable.range(0, n)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(new Consumer<Integer>() {
    @Override
    public void accept(Integer integer) throws Exception {
        final int index = integer;

        Single<ResponseBody> singleGetChannels = aPI.getChannels(mUserUrls.getM3u().get(integer))
                                    .subscribeOn(Schedulers.newThread())
                                    .observeOn(AndroidSchedulers.mainThread());

        Single<List<EPG>> singleGetEPGs = aPI.getEPGs(mUserUrls.getJson())
                                    .subscribeOn(Schedulers.newThread())
                                    .observeOn(AndroidSchedulers.mainThread());


        Single.zip(singleGetChannels, singleGetEPGs, new BiFunction<ResponseBody, List<EPG>, ChannelsAndEPG>() {
            @Override
            public ChannelsAndEPG apply(ResponseBody responseBodyChannels, List<EPG> ePGs) {

                ChannelsAndEPG channelsAndEPG = new ChannelsAndEPG(responseBodyChannels, ePGs);

                return channelsAndEPG;
            }
        }).subscribe(new SingleObserver<ChannelsAndEPG>() {
                                @Override
                                public void onSubscribe(Disposable d) {

                                }

                                @Override
                                public void onSuccess(ChannelsAndEPG channelsAndEPG) {
                                    m3Us.put(index, M3UParser.parseList(channelsAndEPG.mResponseBodyChannels.byteStream()));


                                    setEPGs(index, channelsAndEPG.mEPG);
                                    setEPGsForNext24Hours();

                                    counter--;
                                    if (counter == 0) {
                                        if (mCallback != null) {
                                            isDataLoaded = true;
                                            mCallback.onDataLoaded();
                                        }
                                    }

                                }

                                @Override
                                public void onError(Throwable e) {

                                }
                            });
                        }
                    })
                    .subscribe(new Observer<Integer>() {

                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onNext(Integer integer) {

                        }

                        @Override
                        public void onError(Throwable e) {

                        }

                        @Override
                        public void onComplete() {
                            Log.i(TAG, "onComplete called");

                        }
                    });

2 个答案:

答案 0 :(得分:1)

您可以使用flatMap将每个整数转换为Single(与现在相同)。然后调用toList来获取Single。

答案 1 :(得分:1)

您可以使用:

Observable.fromIterable(mUserUrls.getM3u())
          .flatMap{  m3u -> 
               aPI.getChannels(m3u.getInteger)
                  .zipWith(aPI.getEPGs(mUserUrls.getJson()))
                  .subscribeOn(Schedulers.io())
          }
          .doOnNext{
              m3Us.put(index, M3UParser.parseList(channelsAndEPG.mResponseBodyChannels.byteStream()));
              setEPGs(index, channelsAndEPG.mEPG);
              setEPGsForNext24Hours();
          }
          .subscribe(new Observer<Integer>() {

                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer integer) {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {
                        Log.i(TAG, "onComplete called");

                    }
                })