1

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

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

让检查我的代码

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

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

太感谢了

4

2 回答 2

1

任何操作员(包括share)实际上都会创建一个新的 Sub-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>

于 2017-12-04T10:42:55.987 回答
0

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

  • BehaviorSubjectobj. _

  • Subject里面的实例.share()

请记住,只有当您订阅它时才会BehaviorSubject发出它的缓存值。

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

然后创建一个t以操作符结尾的链share()

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

最后一行您再次订阅t.subscribe. 就像以前 this 订阅Subjectinside 一样share()。但是share()已经订阅了它的源 Observable,所以它不会进行另一个订阅。这就是多播和multicast()运营商的意义所在。

这就是为什么您不会看到任何subscribe 2 10内容,也不会看到mapped打印两次的原因。您订阅的是Subject内部share(),而不是来源BehaviorSubject

于 2017-12-04T12:10:25.990 回答