我有一个关于多重观察和我注意到的意外(对我而言)行为的问题。
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})`);
});
因此,有一个共享的observable a,每次点击事件都会发出1。由于startWith运算符,会发出-1。 可观察的b只是通过配对来自a。
的最新两个值来创建一个新的observable我的期望是:
[-1, 1] // first click
[ 1, 1] // all other clicks
我观察到的是:
[1, 1] // from second click on, and all other clicks
我注意到,值-1立即发出并被Sub 1消耗,甚至在Sub 2订阅了observable之前,由于a是多播的,因此Sub 2对于派对来说太迟了。
现在,我知道我可以通过BehaviourSubject进行多播,而不是使用startWith运算符,但是当我使用startWith和通过共享进行多播时,我想了解这种情况的用例。
据我了解,每当我使用.share()和.startWith(x)时,只有一个订阅者会收到有关startWith值的通知,因为所有其他订阅者都是在发出值后订阅的。
这是通过一些特殊主题(行为/重播......)进行多播的原因,还是我错过了关于这个startWith / share场景的内容?
谢谢!
答案 0 :(得分:9)
这实际上是正确的行为。
.startWith()
向每个新订阅者发出其值,而不仅仅是第一个订阅者。 b.subscribe(([prevA, curA])
永远不会收到它的原因是因为您正在使用.share()
(又名.publish().refCount()
)进行多播。
这意味着第一个a.subscribe(...)
会使.refCount()
订阅其来源,并且会保留订阅(请注意,Observable .fromEvent(someDom, 'click')
永远不会完成)。
然后,当您最终致电b.subscribe(...)
时,它只会订阅Subject
内的.share()
,并且永远不会通过.startWith(-1)
,因为它已被多播且已在{{{}}中订阅1}}。