Rxjs combineAll与双地图包装

时间:2017-07-24 10:49:48

标签: rxjs observable angularfire2

我正在使用AngularFire2。我想检索用户聊天列表,并为每个聊天确定在用户离开聊天后是否发出了最后一条消息。

为此,我通过返回FirebaseListObservable的函数getUserChatList()检索聊天列表。

看起来我们不能直接在列表中使用map运算符,我们需要对它进行双重映射。

完成后我会检索每个聊天的最后一条消息,如果我确定一条消息未读,我将anyUnread变量设置为true。

我必须等待每个聊天都已处理好,所以我使用了combineAll()。

看起来我的代码永远不会转到最后一个映射(return语句)。知道我做错了吗?

watchUnreadMessages() {
    // Retrieve all chats
    this.subscription =
    this.msgService.getUserChatList()
    .map( chats => {
      chats.map( chat => {
        console.log('chat ', chat)
        let lastPresence = chat.lastPresence;
        return this.msgService.getLastMessage(chat.$key)
        .map( lastMess => {
          console.log('lastMess ', lastMess)
          if (lastMess[0].timestamp >= lastPresence)
          this.anyUnread = true;
        });
      })
    })
    .combineAll( () => {
      let unread = this.anyUnread;
      return unread
    }).subscribe( (unread) => console.log('unread: ', unread) );


  }

*编辑* 试图使用mergMap作为@kit建议使用简单的例子但在我的情况下仍然有一些阻塞错误

首先尝试简单:

this.msgService.getUserChatList().flatMap( chats =>
      Observable.from(chats).flatMap( (chat, i) => {
            console.log ('chat, ', chat);
            return Observable.of(chat);
      })
      .last()
    )
    .subscribe( () => console.log('Finished') )

显示chat1,chat2并完成(订单完美)。请注意,聊天包含诸如$ key和lastPresence之类的属性。

现在我想增加复杂性:

this.msgService.getUserChatList()
      .flatMap( chat => {
        return this.msgService.getLastMessage(chat.$key).map( lastMess => {
          return this.containsUnreadMessages(lastMess, chat.lastPresence);
        })
      } )
      .last()
    )
    .subscribe( () => console.log('Finished') )

代码甚至无法编译,因为调试器告诉我属性$ key和lastPresence在{}类型中不存在......这让我发疯了!

1 个答案:

答案 0 :(得分:0)

好的,这可以做得更好,但也许你会从中得到一些灵感:

const arr = [
    [{timestamp: 1}],
    [{timestamp: 1}],
    [{timestamp: 3}],
];

Rx.Observable.from([
    {lastPresence: 1},
    {lastPresence: 2},
    {lastPresence: 3},
])
.flatMap((chat, i) => {
    return Rx.Observable.of(arr[i]).map((lastMess) => lastMess[0].timestamp >= chat.lastPresence ? 1:0);
})
.scan((counter, one) => counter + one, 0)
.last()
.subscribe((unread) => console.log('unread: ', unread));