当我订阅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
抱歉天真的问题。有没有人可以向我解释这个?
非常感谢
答案 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;
答案 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
。