RxJava / Retrofit 调用响应中的每个项目



我用 retrofit/rxJava 调用我的 API,我得到一个可观察的响应,就像BreedDog单一列表一样

.你可以看到我的代码:

compositeDisposable.add(breedDogsDisplayDataRepository.getBreedDogs(name)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableSingleObserver<List<BreedDog>>() {
@Override
public void onSuccess(List<BreedDog> breedDogList) {
Log.e("test", "okPresenter");
view.displayBreedDogs(breedDogToViewModelMapper.map(breedDogList));
}
@Override
public void onError(Throwable e) {
Log.e("test", "errorPresenter : " + e.toString());
// handle the error case
System.out.println(e.toString());
}
}));

这有效,但现在,对于此列表中的每个项目,我需要调用我的 API 来获取 URL 图像并更新我的列表。 但我不知道怎么做...我尝试在可观察中更改我的单一响应,并使用像flatMap或flatMapIterate这样的运算符。等等,但是我一直在对象上遇到错误。就像没有实例...等

这是一个例子:

breedDogsDisplayDataRepository.getBreedDogs(name)
.flatMapIterable(breedDogs -> breedDogs)
.map( item ->   breedDogsDisplayDataRepository.getImageBreedDog(item.getId())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableSingleObserver<List<BreedImageResponse>>() {
@Override
public void onSuccess(List<BreedImageResponse> breedImageResponses) {
}
@Override
public void onError(Throwable e) {
Log.e("test", "errorPresenter : " + e.toString());
// handle the error case
System.out.println(e.toString());
}
})));

我用好方法吗?还是需要改变一些东西?

如果没有存储库的签名,很难确切地说出出了什么问题,但您确实提到getBreedDogs返回了一个Single<List<BreedDogs>>。如果是这样的话,据我所知,Single没有flatMapIterable,但它有flattenAsObservable可以用来做你想做的事。

它将映射单个内部的列表,并将其项目作为可观察量发出。这意味着您不能再使用map并且必须切换到flatMap

.flattenAsObservable(breedDogs -> breedDogs) 
.flatMapSingle(item -> breedDogsDisplayDataRepository.getImageBreedDog(item.getId()))

使用flatMapSingle是因为在这种情况下我们是平面映射Singles

我注意到的另一件事是,您的"订阅部分"在map内,您希望将其从中取出。 因此,理想情况下,您可以像以下方式搬到外面:

.flattenAsObservable(breedDogs -> breedDogs) 
.flatMapSingle(item -> breedDogsDisplayDataRepository.getImageBreedDog(item.getId()))
.subscribeWith(/*...*/);

调度程序由您决定。如果您希望并行下载图像,我建议您将它们保存在flatMapSingle内。

最后一件事,似乎你想收到一个List<BreedImageResponse>,所以我会使用toList()。将所有内容放在一起:

breedDogsDisplayDataRepository.getBreedDogs(name)
.flattenAsObservable(breedDogs -> breedDogs) 
.flatMapSingle(item ->
breedDogsDisplayDataRepository.getImageBreedDog(item.getId())
.subscribeOn(Schedulers.io())
)
.toList()
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableSingleObserver<List<BreedImageResponse>>() {
@Override
public void onSuccess(List<BreedImageResponse> breedImageResponses) { 
}
@Override
public void onError(Throwable e) {}
});

这是我解决问题的解决方案:

public Single<List<BreedDogWithImage>> searchDogs(String name) {
return getBreedDogs(name)
.flatMapIterable(breedDogs -> breedDogs)
.flatMap(breedDog -> getImageBreedDogs(breedDog.getId())
.flatMapIterable(breedDogWithImages -> breedDogWithImages))
.toList();
}

所以我可以这样称呼它:

public void searchBreedDogs(String name) {
compositeDisposable.clear();
compositeDisposable.add(breedDogsDisplayDataRepository.searchDogs(name)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableSingleObserver<List<BreedDogWithImage>>() {
@Override
public void onSuccess(List<BreedDogWithImage> breedDogWithImages) {
Log.e("test", "okCall" + breedDogWithImages);
view.displayBreedDogs(breedDogToViewModelMapper.map(breedDogWithImages));
}
@Override
public void onError(Throwable e) {
Log.e("test", "error ");
e.printStackTrace();
}
}));
}

最新更新