我必须调用返回项目列表的API。对于此列表中的每个项目,我必须调用另一个API(如果列表返回8个项目,我将必须进行8个并行调用)。
我最终必须返回一个列表,我将使用这8个并行调用的结果创建一个列表。
我如何使用RxJava做到这一点?我认为我必须使用flatMap将第一次调用的结果转换为Observable列表,然后我必须使用zip运算符进行并行调用,但我不确定。
请注意我使用RxJava2,没有lambdas表达式。
谢谢!
答案 0 :(得分:3)
你可以这样做,例如,
defer()
允许您仅在订阅时获取数据,然后在项目列表中创建发出所有项目(逐个)的Observable。
然后flatMap()
将创建Observable
来获取每个项目的数据,现在您将拥有发出数据对象的Observable
。
为了收集它,您可以使用toList()
发出单个对象(List
),该对象将包含每个Data
提取的所有Observable
。
注意,为了并行执行,fetchDataFromItem()
订阅Schedulers.io()
非常重要,即使是在io上订阅了所有流。
Observable.defer(new Callable<ObservableSource<Item>>() {
@Override
public ObservableSource<Item> call() throws Exception {
List<Item> items = getItems();
return Observable.fromIterable(items);
}
})
.flatMap(new Function<Item, ObservableSource<Data>>() {
@Override
public ObservableSource<Data> apply(@NonNull Item item) throws Exception {
return fetchDataFromItem(item);
}
})
.toList()
.subscribe(new Consumer<List<Data>>() {
@Override
public void accept(@NonNull List<Data> objects) throws Exception {
//do something with the list of all fetched data
}
});
更新:
如果提取的项目已经Observable
,则defer()
可以替换为flatMapIterable()
,其中包含单个项目列表并将其转换为多个项目的Observable:
getItemsObservable()
.flatMapIterable(new Function<List<Item>, Iterable<Item>>() {
@Override
public Iterable<Item> apply(@NonNull List<Item> items) throws Exception {
return items;
}
})
.flatMap(new Function<Item, ObservableSource<Data>>() {
@Override
public ObservableSource<Data> apply(@NonNull Item item) throws Exception {
return fetchDataFromItem(item);
}
})
.toList()
.subscribe(new Consumer<List<Data>>() {
@Override
public void accept(@NonNull List<Data> objects) throws Exception {
//do something with the list of all fetched data
}
});