[英]Convert Observable<List<Car>> to a sequence of Observable<Car> in RxJava
[英]Convert Observable of List to List of Observables and merge in RxJava
我正在通过创建黑客新闻阅读器应用程序来学习Java。
我想要做的是:
/topstories
发送请求,返回Observable<List<int>>
,在请求完成时发出。 storyId
到Observable<Story>
List<Story>
。 而代码:
private Observable<Story> getStoryById(int articleId) {
BehaviorSubject<Story> subject = BehaviorSubject.create();
// calls subject.onNext on success
JsonObjectRequest request = createStoryRequest(articleId, subject);
requestQueue.add(request);
return subject;
}
public Observable<ArrayList<Story>> getTopStories(int amount) {
Observable<ArrayList<Integer>> topStoryIds = (storyIdCache == null)
? fetchTopIds()
: Observable.just(storyIdCache);
return topStoryIds
.flatMap(id -> getStoryById(id))
// some magic here
}
那我们就像这样使用:
getTopStories(20)
.subscribe(stories -> ...)
你可以试试这样的东西
Observable<List<Integers>> ids = getIdsObservable();
Single<List<Story>> listSingle =
ids.flatMapIterable(ids -> ids)
.flatMap(id -> getStoryById(id)).toList();
然后,您可以订阅该Single以获取List<Story>
请看看我的解决方案。 我更改了你的接口,为getStoryById()返回一个Single,因为它应该只返回一个值。 之后,我为每个Story创建了一个Single请求,并使用Single.zip订阅了所有这些请求。 当所有单打结束时,Zip将执行给定的lambda。 缺点是,所有请求将立即被触发。 如果你不想这样,我会更新我的帖子。 请考虑@elmorabea解决方案还将订阅前128个元素(BUFFER_SIZE = Math.max(1,Integer.getInteger(“rx2.buffer-size”,128));),以及下一个元素饰面。
@Test
void name() {
Api api = mock(Api.class);
when(api.getTopStories()).thenReturn(Flowable.just(Arrays.asList(new Story(1), new Story(2))));
when(api.getStoryById(eq(1))).thenReturn(Single.just(new Story(888)));
when(api.getStoryById(eq(2))).thenReturn(Single.just(new Story(888)));
Flowable<List<Story>> listFlowable =
api.getTopStories()
.flatMapSingle(
stories -> {
List<Single<Story>> collect =
stories
.stream()
.map(story -> api.getStoryById(story.id))
.collect(Collectors.toList());
// possibly not the best idea to subscribe to all singles at the same time
Single<List<Story>> zip =
Single.zip(
collect,
objects -> {
return Arrays.stream(objects)
.map(o -> (Story) o)
.collect(Collectors.toList());
});
return zip;
});
TestSubscriber<List<Story>> listTestSubscriber =
listFlowable.test().assertComplete().assertValueCount(1).assertNoErrors();
List<List<Story>> values = listTestSubscriber.values();
List<Story> stories = values.get(0);
assertThat(stories.size()).isEqualTo(2);
assertThat(stories.get(0).id).isEqualTo(888);
assertThat(stories.get(1).id).isEqualTo(888);
}
interface Api {
Flowable<List<Story>> getTopStories();
Single<Story> getStoryById(int id);
}
static class Story {
private final int id;
Story(int id) {
this.id = id;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.