只要主observable没有发出任何值

时间:2017-07-05 18:37:18

标签: java rx-java reactive-programming rx-java2

以下是我想要实现的目标:

|--------------------A-A-A-A-A-A| primary (behavior subject)
|-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-| secondary (flowable)
|-B-B-B-B-B-B-B-B-B-BA-A-A-A-A-A| result (flowable)

基本上,我正在等待用户输入(通过主要观察),但如果用户尚未输入任何内容,我想提供系统生成的值。收到用户输入后,将不再使用辅助可观察量。

我调查了switchIfEmptycombineLatest,但他们不符合我的需求,因为:

  1. switchIfEmpty 仅在主要观察信号onComplete时有效。
  2. combineLatest 仅在两个observable都发出值
  3. 时才有效

    有没有办法做到这一点?

2 个答案:

答案 0 :(得分:2)

我不确定这是否是最简单或最优雅的方式,但这有效:

const a = Observable.interval(5000);
const b = Observable.interval(1000);

const sharedA = a.shareReplay(1);

const result = b.takeUntil(sharedA).concat(sharedA);

Demo

另一种,也许是简单的方法,将是

const sharedA = a.share();
const result = b.takeUntil(sharedA).merge(sharedA);

Demo

答案 1 :(得分:0)

在覆盖您对已接受答案的评论中......即:

  

用户想要订购。他可以手动设置一个取件位置(可观察到的a),否则我们提供gps位置(可观察的b)作为取件位置。现在,如果用户点击了我的位置"按钮在地图上,然后我们想返回gps位置作为提供者。

您有三个源流:

  • a:当前GPS位置(纬度/经度对的流)。
  • b:手动选择lat / lon(lat / lon对流)。
  • c:按钮点击(虚空流)。

我在RxSwift中写了这个而不是RxJava,但希望你能翻译:

extension Observable {
    static func switchBetween(_ a: Observable<Element>, _ b: Observable<Element>, using trigger: Observable<Void>) -> Observable<Element> {
        return Observable.create { observer in
            let lock = NSRecursiveLock()
            var withB = false
            let disposeA = a.subscribe({ event in
                if withB == false {
                    observer.on(event)
                }
            })
            let disposeB = b.subscribe({ event in
                lock.lock(); defer { lock.unlock() }
                withB = true
                observer.on(event)
            })
            let disposeTrigger = trigger.subscribe({ event in
                if case .next = event {
                    lock.lock(); defer { lock.unlock() }
                    withB = false
                }
            })
            return Disposables.create(disposeA, disposeB, disposeTrigger)
        }
    }
}

可以像这样调用:

Observable.switchBetween(a, b, using: c)