RxJava-获取列表中的每个项目
我有一个方法,返回一个RxJava-获取列表中的每个项目,java,monads,reactive-programming,rx-java,Java,Monads,Reactive Programming,Rx Java,我有一个方法,返回一个可观察的,它是一些项目的ID。我想浏览一下这个列表,并使用另一个返回Observable的方法下载每个项目 如何使用RxJava操作符实现这一点?这里是一个小型的自包含示例 public class Example { public static class Item { int id; } public static void main(String[] args) { getIds()
可观察的
,它是一些项目的ID。我想浏览一下这个列表,并使用另一个返回Observable
的方法下载每个项目
如何使用RxJava操作符实现这一点?这里是一个小型的自包含示例
public class Example {
public static class Item {
int id;
}
public static void main(String[] args) {
getIds()
.flatMapIterable(ids -> ids) // Converts your list of ids into an Observable which emits every item in the list
.flatMap(Example::getItemObservable) // Calls the method which returns a new Observable<Item>
.subscribe(item -> System.out.println("item: " + item.id));
}
// Simple representation of getting your ids.
// Replace the content of this method with yours
private static Observable<List<Integer>> getIds() {
return Observable.just(Arrays.<Integer>asList(1, 2, 3));
}
// Replace the content of this method with yours
private static Observable<Item> getItemObservable(Integer id) {
Item item = new Item();
item.id = id;
return Observable.just(item);
}
}
使用修改源可观察对象的,使用函数调用其上的flatMap
。您可以将其视为一个两步过程:
Iterable
),并将其作为一个可观察的
flatMap
将每个发出的可观察的对象合并为一个可观察的
public class FlattenTransform<T> implements Observable.Transformer<Iterable<T>, T> {
@Override
public Observable<? extends T> call(Observable<? extends Iterable<T>> source) {
return source.flatMap(new Func1<Iterable<T>, Observable<T>>() {
@Override
public Observable<T> call(Iterable<T> values) {
return Observable.from(values);
}
});
}
}
使用compose
和Transformer
而不是flatMap
和Func1
的优点是,如果将来需要再次展平列表,您甚至不必考虑使用哪个操作符(map?flatMap?concatMap?)。换句话说,flatmap操作被烘焙到FlatTransform类中,细节被抽象掉
转换器还有其他好处,例如能够将多个操作链接在一起。作为
flatMapIterable
的替代方案,您可以通过以下方式实现:
在Kotlin中,使用
flattasflowable
:
repository.getFlowableData(id)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.toList()
.flattenAsFlowable { it }
.map { someMethod(it) }
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ },
{ onError(it) })
为科特林
Observable
.fromIterable(listOfChallenges) // list of challenges which contain challenge ID
.flatMap { eachChallenge ->
getChallengeDetail(eachChallenge.challengeUid!!) // fetch details of each challenge
}
.toList() // map to list
.subscribe({ listOfEachChallengesDetail ->
}, {
// error
})
您还可以执行Observable.from(Arrays.asList(…),而不需要FlatMapiteTable您救了我的命。谢谢,很好的例子。谢谢。@Miguel你能看看这个问题吗?订购很重要吗?不太重要,但出于教育目的,我很想看到两种版本。请看这个问题:
Observable.just(Arrays.asList(1, 2, 3)) //we create an Observable that emits a single array
.flatMap(numberList -> Observable.fromIterable(numberList)) //map the list to an Observable that emits every item as an observable
.flatMap(number -> downloadFoo(number)) //download smth on every number in the array
.subscribe(...);
private ObservableSource<? extends Integer> downloadFoo(Integer number) {
//TODO
}
Observable.just(Arrays.asList(1, 2, 3))
.flatMap(Observable::fromIterable)
.flatMap(this::downloadFoo)
repository.getFlowableData(id)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.toList()
.flattenAsFlowable { it }
.map { someMethod(it) }
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ },
{ onError(it) })
Observable
.fromIterable(listOfChallenges) // list of challenges which contain challenge ID
.flatMap { eachChallenge ->
getChallengeDetail(eachChallenge.challengeUid!!) // fetch details of each challenge
}
.toList() // map to list
.subscribe({ listOfEachChallengesDetail ->
}, {
// error
})