【问题标题】:Rxjs: Merge two streams with one stream that depends of anotherRxjs:将两个流与一个依赖于另一个的流合并
【发布时间】:2017-11-06 16:46:46
【问题描述】:

我有一个流调用一个服务,该服务返回一个流,该流需要原始流的信息来进行请求。

this.messages$ = this.selectedChat$
.switchMap(chat => this.chatService.subscribeMessages(chat.room))
.map(messages) =>
  messages.map((message: any) => {
    //Here need add information of the chat object
    return message;
  })
);

我看到的所有可以合并流并在以后分离它们的运算符(如combineLatest)接收参数,因此,我不能使用原始流信息来调用生成另一个流的服务,我会不喜欢在原始流上使用 subscribe 并在 subscribe 中返回一个新流,因为它的代码有点乱。

有什么建议吗?

【问题讨论】:

    标签: javascript angular stream rxjs


    【解决方案1】:

    switchMap 操作中使用selector function

    this.messages$ = this.selectedChat$
    .switchMap(chat => this.chatService.subscribeMessages(chat.room), 
    (chat,messages)=>({chat,messages})) // create a new object, using the inner observable and the mapped one
    .map(data =>
      data.messages.map((message: any) => {
        // Here data.chat has the chat information
        return message;
      })
    );
    

    有关switchMap 运算符的更多信息,请查看here

    【讨论】:

    • 我认为最好的解决方案是保持代码的可读性和扁平化。谢谢!
    • 很高兴它有帮助:)
    【解决方案2】:

    类似的东西?

    this.messages$ = this.selectedChat$
    .switchMap(chat => {
    // chat still within the scope
      return this.chatService.subscribeMessages(chat.room))
        .map(messages) =>
           messages.map((message: any) => {
           //Here need add information of the chat object
           return message;
         })
    });
    

    如果你坚持要传递变量你可以试试

    this.messages$ = this.selectedChat$
    .switchMap(chat =>this.chatService.subscribeMessages(chat.room).combineLatest(Observable.of(chat)))
        .map([messages,chat]) =>
           messages.map((message: any) => {
           //Here need add information of the chat object
           return message;
         })
    });
    

    如果需要太多全局值,您还可以使用 Behavior 主题设置全局变量存储

    【讨论】:

      【解决方案3】:

      我知道这个问题已经得到解答,但我很好奇 - 在我看来,这就像括号和缺少的回报混淆。

      原文:

      this.messages$ = this.selectedChat$
      .switchMap(chat => this.chatService.subscribeMessages(chat.room))
      .map(messages) =>
        messages.map((message: any) => {
          //Here need add information of the chat object
          return message;
        })
      );
      

      这看起来像是一个错字.map(messages) =>

      我试过了

      const selectedChat$ = Observable.of({ room: '1', chatter: 'me', chattee: 'you' })
      const subscribeMessages = (room) => Observable.of(['msg1', 'msg2'])
      
      const messages$ = selectedChat$
        .switchMap(chat => subscribeMessages(chat.room)
          .map(messages => {
            return messages.map(message => {
              //Here need add information of the chat object
              return [message, chat];
            })
          })
        )
      
      messages$.subscribe(console.log)
      

      并在应用适当的关闭后得到一个包含聊天的结果。

      我的测试 observables 的形状有误,还是误解了要求?

      【讨论】:

      • 是的,这很好用,但是,在我个人看来,不将链嵌套在多个级别上会更易读
      • 它的嵌套层数与接受的答案完全相同,区别仅在于缩进。
      • 在第一个视图中,我看不到地图是在主要流上还是在 subscribedMessages 上。但这只是我个人的看法,也许其他人更喜欢这种解决方案。
      • 当然,很公平 - 每个人都有自己喜欢的布局。实际上,我通常会做更多的缩进,例如 subscribeMessages(chat.room) 会在它自己的行上,并且后面的所有内容都会缩进更多。
      • 我想重要的是要证明这可以在不使用 selector function 的情况下完成,并且 chat 被闭包捕获,这是一个有用的概念。
      猜你喜欢
      • 1970-01-01
      • 2021-09-18
      • 1970-01-01
      • 1970-01-01
      • 2021-04-24
      • 2019-04-16
      • 2020-03-20
      • 2021-06-15
      • 2020-04-21
      相关资源
      最近更新 更多