Rxjs 不执行对BehaviorSubject的共享映射的第二次订阅
当我从Rxjs 不执行对BehaviorSubject的共享映射的第二次订阅,rxjs,behaviorsubject,Rxjs,Behaviorsubject,当我从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.sub
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
对不起,这个天真的问题。有人能给我解释一下吗
非常感谢任何操作符(包括共享
)实际上都会创建一个新的子可观察对象,它有自己的共享/重播属性,这些属性与源可观察对象分离
因此,要获得结果,应该使用publishReplay(1)
而不是share()
。
(当然,您必须使用refCount()
或connect()
)
const obj=新接收行为主体(1)
obj.subscribe(console.log)
常数t=obj.map(u=>{
控制台.log(“映射”)
返回u*10
}).publishReplay(1)
.refCount();
t、 订阅(x=>console.log(“订阅1”+x))
t、 订阅(x=>console.log(“订阅2”+x))
//在以下行未注释的情况下,两个订阅都打印出新值
//目标下一步(2)
在您的示例中,您有两个主题:
中的obj
BehaviorSubject
实例内Subject
.share()
BehaviorSubject
仅当您订阅它时才会发出它的缓存值
第一个观察者obj.subscribe(console.log)
直接订阅BehaviorSubject
。这将打印1
然后创建一个链t
,该链以share()
操作符结尾
现在您可以使用t.subscribe
订阅t
。这意味着您在share()
中订阅主题
,因为这是它的第一个观察者,所以它需要订阅它的源观察者(这反过来到达发出缓存值的源BehaviorSubject
)。请注意,share()
只是将运算符与refCount()
一起使用的快捷方式
最后一行您再次使用t.subscribe
订阅。就像前面一样,这订阅了主题内部共享()
。但是,share()
已经订阅了它的源可观察对象,因此它不会再订阅一次。这就是多播的要点和multicast()
操作符
这就是为什么您不会看到任何subscribe210
,也不会看到mapped
打印两次的原因。您订阅的是共享()中的主题
,而不是源行为主题
您知道如何将一个行为主题
映射到另一个行为主题
。我不想在每个订阅上重复map
中的逻辑,只需要在原始BehaviorSubject
实例(obj
)发出新值时运行此逻辑。换句话说,我想要一些东西打印出我的问题的预期结果,我想我的答案来自@olsn的答案。非常感谢。