因此,我有一个轨道ID列表,对于每个轨道ID,我需要执行一个网络请求以获取轨道详细信息,我使用了一个for循环来启动所有请求,并使用一个闩锁来等待所有请求完成。完成后,将使用已填充的轨道列表发送回调。

我想知道是否有更好的方法可以做到这一点,也许使用RxJava?

我在Android中使用Retrofit 2.0。

    public IBaseRequest batchTracksById(final TrackIdList trackIdListPayload, final IRequestListener<TracksList> listener) {
    final TracksList tracks = new TracksList();
    final Track[] trackArray = newrack[trackIdListPayload.getTrackIds().length];
    tracks.setTrack(trackArray);

    final CountDownLatch latch = new CountDownLatch(trackArray.length);


    Thread t = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                latch.await();
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        listener.onRequestUpdate(null, tracks, null, true);
                    }
                });

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });
    t.start();

    for (String id : trackIdListPayload.getTrackIds()) {
        getTrackById(id, new IRequestListener<Track>() {
            @Override
            public void onRequestFailure(IBaseRequest request, Exception exception) {
                latch.countDown();
            }

            @Override
            public void onRequestUpdate(IBaseRequest request, Track track, RequestState state, boolean requestComplete) {
                //iterate through the tracks and update the ones in the thing

                int i = 0;
                for (String s : trackIdListPayload.getTrackIds()) {
                    if (s.equals(track.getTrackId())) {
                        trackArray[i] = track;
                        // don't break here, as we may have a case where we have multiple instances of the same trackId (although
                        // at the moment a request will be made for each anyway...
                    }
                    i++;
                }

                latch.countDown();
            }
        });
    }

    return null;
}

最佳答案

如果要异步发出所有请求并等待它们返回,则可以执行以下操作(出于简洁和易读性考虑使用lambda):

tracks.flatMap(track -> getTrackDetails(track.id)
                          .subscribeOn(Schedulers.io()))
      .toList()
      .doOnNext(list -> processTrackList())
      ...

如果您需要按tracks的顺序返回结果,但是仍然异步请求,那么在即将发布的rxjava 1.0.15中,您将可以执行此操作
tracks.concatMapEager(track -> getTrackDetails(track.id)
                          .subscribeOn(Schedulers.io())
      .toList()
      .doOnNext(list -> processTrackList())
      ...

09-10 06:32
查看更多