为什么在 `withLatestFrom` 中的可观察对象上使用 `share` 运算符会导致在其中一个订阅中跳过某个事件?

Why using the `share` operator on the observable in `withLatestFrom` will result in an event being skipped in one of the subscriptions?

使用以下代码:

let stringSubject = BehaviorSubject<String?>(value: nil).share()
let intSubject = BehaviorSubject<Int?>(value: nil)

let intObservable = intSubject.compactMap { [=10=] }

let resultingSequence = intObservable
    .take(1)
    .withLatestFrom(stringSubject) { ([=10=], ) }
    .filter { [=10=].1 == nil }
    .map { [=10=].0 }

let subscriptionB = resultingSequence
    .skip(1)
    .subscribe(onNext: { print("Subscription B: \([=10=])") })

let subscriptionA = resultingSequence
    .subscribe(onNext: { print("Subscription A: \([=10=])") })

intSubject.onNext(1)

print("Finished")

我期待的是事件 1 将由 subscriptionA 处理,即打印如下内容:

Subscription A: 1
Finished

但在实际结果中没有打印任何内容,即

Finished

但是,如果删除 stringSubjectshare(),或者将 share() 添加到 resultingSequence 声明的末尾,则预期结果将是印刷。

这背后的原因是什么?

因为你的resultingSequence没有分享,所以stringSubject有两个订阅。 .share() 有一个参数 replay 定义将向未来的订阅者重放多少先前发出的序列元素,此参数的默认值为 0。

因此,当您执行 stringSubject.share() 时,第一个订阅将收到初始值 (nil),但任何后续订阅都不会收到任何值,因为 stringSubject 现在已发出其初始值并且您已告知它向新订阅者重播 0 个先前发出的元素。

.share() 更改为 .share(replay: 1) 也会提供您想要的输出,因为已经发出的初始值将重播给任何新订阅者。