我进行了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");
}
});
答案 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");
}
})