我有一个关于多播可观察对象和我注意到的意外(对我而言)行为的问题。
const a = Observable.fromEvent(someDom, 'click')
.map(e => 1)
.startWith(-1)
.share();
const b = a.pairwise();
a.subscribe(a => {
console.log(`Sub 1: ${a}`);
});
a.subscribe(a => {
console.log(`Sub 2: ${a}`)
});
b.subscribe(([prevA, curA]) => {
console.log(`Pairwise Sub: (${prevA}, ${curA})`);
});
因此,存在一个共享的可观察变量a,该变量在每个点击事件中均发出1。由于startWith运算符,发出-1。
可观察对象b只是通过配对a中的最新两个值来创建一个新的可观察对象。
我的期望是:
[-1, 1] // first click
[ 1, 1] // all other clicks
我观察到的是:
[1, 1] // from second click on, and all other clicks
我注意到的是,在偶数Sub 2订阅可观察对象之前,Sub-1立即发出并消耗了值-1,并且由于a是多播的,因此Sub 2对于该方而言为时已晚。
现在,我知道我可以通过BehaviourSubject进行多播,而不使用startWith运算符,但是当我使用startWith和通过share进行多播时,我想了解这种情况的用例。
据我了解,每当我使用.share()和.startWith(x)时,只有一个订户会收到有关startWith值的通知,因为所有其他订户都在发出该值后进行了预订。
那么,这是否是通过某些特殊主题(行为/重播...)进行多播的原因,还是我缺少有关startWith/share场景的内容?
谢谢!
最佳答案
这实际上是正确的行为。.startWith()
将其值发送给每个新订户,而不仅仅是第一个。 b.subscribe(([prevA, curA])
从未收到的原因是因为您正在使用.share()
(也称为.publish().refCount()
)进行多播。
这意味着第一个a.subscribe(...)
使.refCount()
订阅其源,并且它将保持订阅状态(请注意,可观察到的.fromEvent(someDom, 'click')
永远不会完成)。
然后,当您最终调用b.subscribe(...)
时,它将仅订阅Subject
中的.share()
,并且永远不会经过.startWith(-1)
,因为它已被多播并且已经在.share()
中进行了订阅。
关于rxjs - 共享的observable和startWith运算符,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42021745/