我有一个关于多播可观察对象和我注意到的意外(对我而言)行为的问题。

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/

10-13 07:37