我有一个关于多播可观察性和我注意到的意外行为的问题。
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-1是由于startWith运算符而发出的。可观测b只是通过将a的最新两个值配对来创建一个新的可观测值。
我的期望是:
[-1, 1] // first click
[ 1, 1] // all other clicks
我观察到的是:
[1, 1] // from second click on, and all other clicks
我注意到的是,值-1立即被Sub 1发出并消耗,甚至在Sub 2订阅可观察到的之前,而且由于a是多播的,所以Sub 2对一方来说太晚了。
现在,我知道我可以通过BehaviourSubject进行多播,而不使用startWith运算符,但我想了解当我使用startWith和通过共享进行多播时,这种场景的用例。
据我所知,每当我使用.share()和.startWith(x)时,只有一个订阅者会收到startWith值的通知,因为所有其他订阅者都是在发出值后订阅的。
那么,这是通过一些特殊主题(行为/回放…)进行多播的原因吗?还是我错过了这个startWith/share场景的一些内容?
谢谢!
这实际上是正确的行为。
.startWith()
将其值发送给每个新订户,而不仅仅是第一个订户。b.subscribe(([prevA, curA])
从未接收到它的原因是因为您正在使用.share()
(也称为.publish().refCount()
)的多播。
这意味着第一个a.subscribe(...)
使.refCount()
订阅其源,并且它将保持订阅状态(注意,Observable.fromEvent(someDom, 'click')
永远不会完成)。
然后,当您最终调用b.subscribe(...)
时,它将只订阅.share()
中的Subject
,并且永远不会通过.startWith(-1)
,因为它是多播的,并且已经在.share()
中订阅了。