我有一些我可以并行执行的observable,例如localObservable
和networkObservable
。如果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());
答案 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);
}