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的答案。非常感谢。