我想要组合两个observable,一个发出n个项目,另一个只发生1个。
combineLatest
将等到两个observable都至少发出一个项目,然后组合最新发出的项目,直到两个observable都完成。请按照时间顺序考虑:
combineLatest
只会将可观察1的结果2与可观察2的结果1结合起来(可以很容易地在这里测试:http://rxmarbles.com/#combineLatest)。
我需要什么
我需要组合两个可观察对象的所有项目,无论哪个更快。我怎么能这样做?
结果应该是(始终独立于哪个观察者首先开始发射物品!):
答案 0 :(得分:1)
旧问题,但我遇到了同样的问题。这是我的目的。首先,非工作版本:
Observable<Integer> emitsMany = Observable.range( 1, 10 )
.concatMap( i -> Observable.just( i ).delay( 1, TimeUnit.SECONDS ))
.doOnNext( i -> System.out.println( "produced " + i ));
Observable<Boolean> emitsOne = Observable.just( true )
.delay( 3, TimeUnit.SECONDS )
.doOnNext( b -> System.out.println( "produced " + b ));
Observable.combineLatest(
emitsMany, emitsOne,
( i, b ) -> "consumed " + i + " " + b )
.blockingSubscribe( System.out::println );
果然,emitsMany
的前几对排放被丢弃:
produced 1
produced 2
produced 3
produced true
consumed 3 true
produced 4
consumed 4 true
. . .
我认为这是解决方法。首先,我们需要将emitsOne
包装到可以继续返回先前观察到的值而不会延迟的内容中。我不知道要执行此操作的操作员,但是BehaviorSubject
可以完成这项工作。
接下来,我们可以将concatMap
与嵌套的take(1) Observable
一起使用:
Observable<Integer> emitsMany = Observable.range( 1, 10 )
.concatMap( i -> Observable.just( i ).delay( 1, TimeUnit.SECONDS ))
.doOnNext( i -> System.out.println( "produced " + i ));
Observable<Boolean> emitsOne = Observable.just( true )
.delay( 3, TimeUnit.SECONDS )
.doOnNext( b -> System.out.println( "produced " + b ));
BehaviorSubject<Boolean> emitsOneSubject = BehaviorSubject.create();
emitsOne.subscribe( emitsOneSubject::onNext );
emitsMany.concatMap( i -> emitsOneSubject
.take( 1 )
.map( b -> "consumed " + i + " " + b ))
.blockingSubscribe( System.out::println );
我们现在获得了所有组合:
produced 1
produced 2
produced true
consumed 1 true
consumed 2 true
produced 3
consumed 3 true
produced 4
consumed 4 true
produced 5
consumed 5 true
produced 6
consumed 6 true
produced 7
consumed 7 true
produced 8
consumed 8 true
produced 9
consumed 9 true
produced 10
consumed 10 true
答案 1 :(得分:0)
请注意,这是未经测试的:
从可观察序列a
创建ReplaySubject。对于按序列b
发出的每个值,将该值与重播主题组合以创建新的Pair <A, B>
可观察值。将这些可观察对象平面映射并将其作为结果返回。
public static <A, B> Observable<Pair<A, B>> permutation(
Observable<A> observableA,
Observable<B> observableB,
) {
ReplaySubject<A> subjectA = ReplaySubject.create();
observableA.subscribe(subjectA::onNext);
return observableB.flatMap(b -> subjectA.map(a -> Pair.of(a, b)));
}