Javascript Rx(JS):如何在flatMap流中更新订阅

Javascript Rx(JS):如何在flatMap流中更新订阅,javascript,rxjs,cyclejs,Javascript,Rxjs,Cyclejs,我有一个状态$stream,它包含消息$s,它是消息$stream的数组。状态$已更新,并显示新消息$ 我希望订户在一个单一流中处理来自所有messages$的消息,并且我希望此流只包含正确的事件 我每次都尝试将合并的消息$flatMap,但问题是旧消息$s(在以前的状态中为$value)被多次订阅 我如何解决这个问题 让allMessages$=state$.flatMap(s=>{ 返回可观察的。合并(s.messages$s) } ) allMessages$.subscribe((x)

我有一个状态$stream,它包含消息$s,它是消息$stream的数组。状态$已更新,并显示新消息$

我希望订户在一个单一流中处理来自所有messages$的消息,并且我希望此流只包含正确的事件

我每次都尝试将合并的消息$flatMap,但问题是旧消息$s(在以前的状态中为$value)被多次订阅

我如何解决这个问题


让allMessages$=state$.flatMap(s=>{
返回可观察的。合并(s.messages$s)
}
)
allMessages$.subscribe((x)=>{
console.log('message',x)
//来自单个消息$的消息多次出现
})

问题是,在state$更新后(推送项目),旧的一个会被订阅多次。

州$--s(1)----s(2)----
消息$s[0]--m1----m2----m4--
消息$s[1]--------------m3--------
所有消息$--m1---m2---m3---m4
m1 m4

s(1)-当状态有1条消息$时,s(2)当添加第二条消息$时 因此,allMessages$fire包含来自item1的消息

我想要的是:

州$--s(1)----s(2)-----
消息$s[0]--m1---m2----m4--
消息$s[1]--------------m3--------
所有消息$--m1---m2---m3---m4

这条线显示了简化的情况:

根据您的简化情况,以下是订阅顺序(您可以查看答案,了解热观测值与冷观测值的解释,以及订阅流的理解):

  • 排放
    state1
    • 订阅
      键入$
  • 排放
    state2
    • 订阅
      键入$
    • 订阅
      typing2$
因为您使用的是
flatMap
,所以您同时有三个订阅。如果使用
flatMapLatest
,会发生以下情况:

  • 排放
    state1
    • 订阅
      键入$
  • 排放
    state2
    • flatMapLatest
      中发出的先前流中的“取消订阅”(甚至是英语),即
      Rx.Observable.merge(state.items)
      键入$
    • 订阅
      键入$
    • 订阅
      typing2$
因此,请尝试将
flatMap
替换为
flatMapLatest
,然后告诉我这是否解决了问题


解决这一问题的另一种方法是处理状态变化流,而不是整个状态(redux对react的作用)。

根据您的简化情况,以下是订阅序列(您可以查看答案,了解热观测值与冷观测值的解释,以及订阅流的理解):

  • 排放
    state1
    • 订阅
      键入$
  • 排放
    state2
    • 订阅
      键入$
    • 订阅
      typing2$
因为您使用的是
flatMap
,所以您同时有三个订阅。如果使用
flatMapLatest
,会发生以下情况:

  • 排放
    state1
    • 订阅
      键入$
  • 排放
    state2
    • flatMapLatest
      中发出的先前流中的“取消订阅”(甚至是英语),即
      Rx.Observable.merge(state.items)
      键入$
    • 订阅
      键入$
    • 订阅
      typing2$
因此,请尝试将
flatMap
替换为
flatMapLatest
,然后告诉我这是否解决了问题


解决这一问题的另一种方法是处理状态变化流,而不是整个状态(redux对react的作用)。

很难理解您所说的话。最好是给出一个输入、预期输出和实际输出的示例,并解释差异(就好像您基本上要为您的函数编写测试一样)。我的最佳选择是您必须使用
flatMapLatest
而不是
flatMap
,但如果不了解函数的规格,很难说。Ok尝试绘制。问题是,Resulted sream从同一个流接收多个事件。实际上,我通过添加
distinct()
来做到这一点,因为我是RxJs新手,不确定它的解决方案是否正确。这是否意味着您的问题已解决?我想确认它是正确的解决方案,或者换一个。很难理解你说的话。最好是给出一个输入、预期输出和实际输出的示例,并解释差异(就好像您基本上要为您的函数编写测试一样)。我的最佳选择是您必须使用
flatMapLatest
而不是
flatMap
,但如果不了解函数的规格,很难说。Ok尝试绘制。问题是,Resulted sream从同一个流接收多个事件。实际上,我通过添加
distinct()
来做到这一点,因为我是RxJs新手,不确定它的解决方案是否正确。这是否意味着您的问题已解决?我想确认它是正确的解决方案,或者再买一个。是的,它解决了)非常感谢。我们还必须将share()添加到startWith。Redux方式实际上不起作用。但如果基于状态更改,如何删除现有子选项(当项目从状态中删除时)?是的,这就是为什么“类”的原因。你说得对,在这种情况下,删除可能会使事情变得太复杂。基本上,要删除,您需要终止给定的流。您可以通过添加一个
takeUntil
somew来实现这一点