【发布时间】:2019-01-10 08:16:53
【问题描述】:
在我看来,我有一个微不足道的任务,它似乎对 RX 有非平凡的解决方案。
场景:
我有一个数字生成器列表,该列表应由特定模块使用我不知道的复杂算法聚合。我可以将数字生成器的输出提供给算法。之后,我可以向算法请求一个汇总数字。
我想迭代我所有的数字生成器,直到算法返回一个符合我的条件的数字。
目前的做法:
return generators.getGenerators().flatMapObservable {
Observable
.fromIterable(it)
.flatMap { generator: NumberGenerator ->
generator.getNumber()
.flatMapCompletable { data: NumberData ->
algorithm.inject(data)
}
.andThen(algorithm.getAggregatedNumber())
}
.skipWhile {
it.value == 0.0f || it.value < minLevel
}
.firstOrError()
.toObservable()
}
一些解释:
algorithm 是我班的成员。它具有上面代码使用的两个函数。 inject直接修改getAggregatedNumber返回的结果。
generators.getGenerators() 返回一个 Single>。这是Generators类的接口要求,不能改成Observable。这就是为什么我必须将它映射到 flatMapObservable 中的一个 observable。
每次我将生成器中的数字注入算法时,我都必须检查聚合数字是否符合给定条件(即达到minLevel)。如果是这样,我想返回该单个值并取消订阅剩余的生成器。
换句话说:当条件满足时,剩余的生成器不应该被“执行”,即没有 getNumber() 并且此后不应该发生 algorithm.inject。
一些假设
takeWhile 发出项目,直到满足条件并完成。不幸的是,这将跳过我感兴趣的实际项目。
skipWhile 跳过所有不感兴趣的项目并开始发出我想要的。但是,我只想要匹配条件的第一项,流的其余部分不感兴趣,因此不应发出或执行。
filter 遍历所有仅发出感兴趣项目的内容。但是,由于算法的内部原因,这与skipUntil 的工作方式相同。
simple for-loops:嗯,大部分代码都在使用 Observables 等,所以我认为当我使用 for-loops 中断流,然后从结果中重新创建 observables 时,这是一种破坏。
我希望有人可以指导我如何解决我的问题。
编辑
takeUntil 要求条件 observable 在实际满足条件时发出项目。但是,getAggregatedNumber() 会根据请求发出项目并在之后完成。没有热的 observable 总是在当前值发生变化时发出当前值,所以我可以对其应用过滤器。我怎么能用takeUntil呢?
【问题讨论】:
-
'takeUntil` 应该可以工作。 (来自 Wiki -“此 (takeUntil) 运算符和 takeWhile(Predicate) 之间的区别在于,在这里,在发出项目后评估条件。”) - 发出项目并在检查该条件之后。不是吗?
-
例如,使用
take(1)在filter()之后获取一项。 -
takeUntil是一种有趣的方法。如何使用它作为条件?我知道我请求直到可观察到的聚合数字并在那里过滤发出的项目? -
据我了解您的需求 -
takeUntil正是这样做的“我想迭代我所有的数字生成器,直到算法返回一个符合我的条件的数字。”。您将条件传递给takeUntil运算符。takeUntil将传递项目,直到满足条件(包括最后一项),然后停止。 -
我不清楚你想要什么。您想强制仅将一个元素返回给可观察对象,但该元素必须与条件匹配。我说的对吗?
标签: java android kotlin rx-java2