将单个 Observable 与 Observable.from(array) 组合

Combine Single Observable with Observable.from(array)

给定以下输入:

Observable<Class1> obs = {{super complex long method}}
List<Class2> inputList = {{simple list}}

我希望能够创建以下内容:

Observable<Class3> output

发出将方法 input.transform(Class1 c) 应用于 inputList 中每个输入的结果。

到目前为止我想出的是 zip 和 repeat 的组合:

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-ness):

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);
            }
        });
    }
});