从BehaviorSubject第二次订阅共享映射不会执行

时间:2017-12-04 09:45:58

标签: rxjs behaviorsubject

当我订阅BehaviorSubject实例(t)的共享映射时,只执行第一个订阅。

当原始BehaviorSubjectobj)发出第二个值时,仅打印最新值,并且两个订阅都已执行。

让我们检查一下我的代码

const obj = new Rx.BehaviorSubject(1)
obj.subscribe(console.log)
const t = obj.map(u => {
  console.log("mapped")
  return u * 10
}).share()

t.subscribe(x => console.log("subscribe 1 " + x))
t.subscribe(x => console.log("subscribe 2 " + x))
//with the following line un-commented, both subscriptions print out new value
//obj.next(2)

我的预期结果是

1
mapped
subscribe 1 10
subscribe 2 10

但实际结果是

1
mapped
subscribe 1 10

抱歉天真的问题。有没有人可以向我解释这个?

非常感谢

2 个答案:

答案 0 :(得分:1)

任何运算符(包括share)实际上都会创建一个新的Sub-Observable,它具有与Source-observable分离的自己的共享/重放属性。

为了获得结果,您应该使用publishReplay(1)代替share()。 (使用publishReplay,您当然必须使用refCount()connect()



const obj = new Rx.BehaviorSubject(1)
obj.subscribe(console.log)
const t = obj.map(u => {
  console.log("mapped")
  return u * 10
}).publishReplay(1)
.refCount();

t.subscribe(x => console.log("subscribe 1 " + x))
t.subscribe(x => console.log("subscribe 2 " + x))
//with the following line un-commented, both subscriptions print out new value
//obj.next(2)

<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

在您的示例中,您有两个主题:

  • BehaviorSubject中的obj

  • Subject .share()内的实例。

请注意BehaviorSubject仅在您订阅时才会发出缓存值

第一个观察者obj.subscribe(console.log)直接订阅BehaviorSubject。这会打印1

然后,您创建一个以t运算符结尾的链share()

现在您使用t订阅t.subscribe。这意味着您订阅了Subject share(),因为这是它的第一个观察者,它需要订阅它的源Observable(它反过来到达发出缓存值的源BehaviorSubject) 。请注意,share()只是multicast()运算符与refCount()一起使用的快捷方式。

您使用t.subscribe再次订阅的最后一行。就像之前一样,订阅了Subject里面的share()。但是share()已订阅其源Observable,因此不会再进行其他订阅。这就是多播和multicast()运算符的重点。

这就是为什么你不会看到任何subscribe 2 10而你不会看到mapped两次打印的事件。您订阅了Subject内的share(),而不是来源BehaviorSubject