因此,我有一个轨道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())
...