共享observable和startWith运算符



我有一个关于多播可观察性和我注意到的意外行为的问题。

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()中订阅了。

最新更新