rxjava switch observable如果第二个可观察的开始发出项目

时间:2017-04-18 04:27:16

标签: rx-java

我有一些我可以并行执行的observable,例如localObservablenetworkObservable。如果networkObservable开始发出项目(从这时起,我只需要这些项目),那么丢弃localObservable发出的项目(可能localObservable尚未开始)。

Observable<Integer> localObservable =
            Observable.defer(() -> Observable.range(1, 10)).subscribeOn(Schedulers.io());
Observable<Integer> networkObservable =
            Observable.defer(() -> Observable.range(11, 20)).subscribeOn(Schedulers.io());

2 个答案:

答案 0 :(得分:4)

你可以这样做:

 Observable<Long> networkObservable =
            Observable.interval(1000, 500, TimeUnit.MILLISECONDS)
                    .subscribeOn(Schedulers.io())
                    .share();
    Observable<Long> localObservable =
            Observable.interval(500, TimeUnit.MILLISECONDS)                       
                    .subscribeOn(Schedulers.io())
                    .takeUntil(networkObservable);

    Observable.merge(networkObservable, localObservable)
            .subscribe(System.out::println);

这将输出:

0 // localObservable 
1 // localObservable 
0 // networkObservable from here on
1
2
...

takeUntil会在localObservable发生第一次排放时让networkObservable停止并取消订阅,因此合并的Observable将从localObservable发出networkObservable { {1}}没有启动,当它开始时,它将停止从localObservable发出并切换为仅从networkObservable发出。

答案 1 :(得分:0)

运营商有一个简单的解决方案:AMB

只需查看System.out的输出。

文档:http://reactivex.io/documentation/operators/amb.html

基本上你同时订阅了两个observable,并且可以观察到任何可观察到的第一个发出的东西。另一个可观察的将被取消订阅。

@Test
public void ambTest() throws Exception {
    TestScheduler testScheduler = new TestScheduler();

    Observable<Integer> network = Observable.timer(1000, TimeUnit.MILLISECONDS, testScheduler)
                .concatMap(aLong -> Observable.just(1, 2, 3))
                .doOnSubscribe(disposable -> System.out.println("connect network"))
                .doOnDispose(() -> System.out.println("dispose network"));

    Observable<Integer> local = Observable.timer(500, TimeUnit.MILLISECONDS, testScheduler)
                .concatMap(aLong -> Observable.just(4, 5, 6))
                .doOnSubscribe(disposable -> System.out.println("connect local"))
                .doOnDispose(() -> System.out.println("dispose local"));

    Observable<Integer> integerObservable = Observable.ambArray(network, local);

    TestObserver<Integer> test = integerObservable.test();

    testScheduler.advanceTimeBy(600, TimeUnit.MILLISECONDS);

    test.assertValues(4, 5, 6);

    testScheduler.advanceTimeBy(1000, TimeUnit.MILLISECONDS);

    test.assertValues(4, 5, 6);
}