给定以下输入:
Observable<Class1> obs = {{super complex long method}}
List<Class2> inputList = {{simple list}}
我希望能够创建以下内容:
Observable<Class3> output
发出将方法input.transform(Class1 c)
应用于inputList中的每个输入的结果。
目前我想到的是zip &重复一遍:
Observable<Class3> output = Observable.zip(obs.repeat(), Observable.from(inputList),
(class1, class2) -> class2.transform(class1));
然而,重复的方式太极端了,它在zip启动之前发出多个重复的项目。
我尝试的另一件事是使用combineLatest
,但由于我的List首先发出,我最终只有列表的最后一项与class1实例组合。
还有哪些操作符的组合是有意义的?
您可以直接更改参数顺序,如zip(Observable.from(inputList), obs.repeat(), ...)
。
zip
将订阅第一个Observable
,然后是第二个Observable
。在您的示例中,第一个Observable
是无限的(例如,obs.repeat()
), RxJava将首先请求128项。这就是为什么你看到obs.repeat()
在订阅第二个Observable
之前发出了很多项。
如果将参数顺序更改为Observable.from(inputList), Observable.from(inputList)
, RxJava将首先订阅Observable.from(inputList)
,因为它是一个同步的Observable
, RxJava将消耗它并立即知道它的长度(假设它的长度小于128),然后RxJava将使用这个长度从第二个obs.repeat()
请求项。因此,它不会需要更多的必要项目。
听起来你想做的是从obs
中获取每个输入,将列表中定义的一组函数应用到obs
中的每个项目,然后将输出扁平化回Class3
类型的Observable。在这种情况下,我认为flatMap是一个很好的选择,因为它清楚地表明了意图:您将对每个输入项应用许多函数,然后将流扁平化。
下面是一个示例(请原谅它的java6性):
Observable<Class3> output = obs.flatMap(new Func1<Class1, Observable<Class3>>() {
@Override
public Observable<Class3> call(final Class1 class1) {
return Observable.from(inputList).map(new Func1<Class2, Class3>() {
@Override
public Class3 call(Class2 class2) {
return class2.transform(class1);
}
});
}
});