首页 文章

共享的observable和startWith运算符

提问于
浏览
7

我有一个关于多重观察和一个意外(对我来说)行为的问题,我注意到了 .

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进行多播时,我想了解这种情况的用例 .

据我所知,每当我使用.share()和.startWith(x)时,只有一个订阅者会收到有关startWith值的通知,因为所有其他订阅者在发出值后都会被订阅 .

这是通过一些特殊主题(行为/重播......)进行多播的原因,还是我错过了关于这个startWith / share场景的内容?

谢谢!

1 回答

  • 8

    这实际上是正确的行为 .

    .startWith() 向每个新订阅者发出其值,而不仅仅是第一个订阅者 . b.subscribe(([prevA, curA]) 永远不会收到它的原因是因为你正在使用 .share() (又名 .publish().refCount() )进行多播 .

    这意味着第一个 a.subscribe(...) 使 .refCount() 订阅其源并且它将保持订阅(注意Observable .fromEvent(someDom, 'click') 永远不会完成) .

    然后,当你最终调用 b.subscribe(...) 时,它只会订阅 .share() 内的 Subject ,并且永远不会通过 .startWith(-1) ,因为它已经被多播并且已经在 .share() 中订阅了 .

相关问题