使用 secondary/backup observable 只要 primary observable 没有发出任何值

Use secondary/backup observable as long as primary observable hasn't emitted any value

以下是我要实现的目标:

|--------------------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 仅在两个可观察对象都发出一个值时才有效

有什么办法吗?

我不确定这是最简单还是最优雅的方法,但这行得通:

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

在涵盖您对已接受答案的评论时...即:

A user wants to order a ride. He may set up a pickup location manually (observable a), otherwise we provide gps location (observable b) as pickup location. Now if the user taps "my location" button on the map, then we would like to return to gps location as provider.

您有三个源流:

  • a:当前 GPS 位置(lat/lon 对流。)
  • 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)