代码之家  ›  专栏  ›  技术社区  ›  Sang

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

  •  1
  • Sang  · 技术社区  · 7 年前

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

    当原件 行为主体 ( 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
    

    对不起,这个天真的问题。有人能给我解释一下吗?

    非常感谢你

    2 回复  |  直到 7 年前
        1
  •  1
  •   Olaf Horstmann    7 年前

    任何运营商(包括 share )实际上创建了一个新的子可观察对象,该子可观察对象具有自己的共享/重播属性,这些属性与源可观察对象分离。

    因此,为了获得结果,您应该使用 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>
        2
  •  0
  •   martin    7 年前

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

    • 这个 BehaviorSubject 在里面 obj .

    • Subject 内部实例 .share() .

    行为主体 释放其缓存的值 只有当你订阅时 .

    第一个观察者 obj.subscribe(console.log) 直接订阅 行为主体 . 这张照片 1 .

    然后创建一个链 t 最后是 share() 操作人员

    现在您订阅 t 具有 t.subscribe . 这意味着您订阅了 主题 在…内 共享() 由于这是它的第一个观察者,它需要订阅它的源可观察者(它反过来到达源) 行为主体 释放其缓存值)。请注意 共享() 只是使用 multicast() 操作员 refCount() .

    最后一行你再次订阅 t、 订阅 . 就像之前一样,这订阅了 主题 在…内 共享() . 然而 共享() 已订阅其源可观察,因此 不进行其他订阅 . 这就是多播和 多播() 操作人员

    这就是为什么你不会看到任何 subscribe 2 10 你不会看到 mapped 打印两次。您正在订阅 主题 在…内 共享() ,而不是源 行为主体 .