将observable合并回一个数组

时间:2017-06-19 05:12:59

标签: angular observable

this.groupChatsSub = CEChats.find({
    group: {$in: groupIds}
})
.mergeMap(list => Observable.from(list))
.flatMap((chat: any)=> {
    return this.findLastChatMessage(chat._id, chat.lastMessage).map(lmsgsub=> {
        console.log('lmsgsub', lmsgsub)
        if(lmsgsub) {
            chat.lastMessage = lmsgsub;
            chat.unseen = !lmsgsub.seenBy.some((x)=>x==this.user._id);
            if(chat.unseen) {
                this.groupChatUnseen++;
            }
        } else {
            chat.unseen = false;
        }
        return chat;
    })
})
// .map((sub)=> {
//   console.log(sub);
//   return sub;
// })
.mergeAll();

我正在尝试使我的可观察管道正常工作。

Find从我的数据库中返回一个数组

我使用mergeMap将数组放入一个可观察的数组中,这样我就可以在下一步中访问数组中的每个对象。

然后我使用flatMap处理传入的每个数组项,它调用另一个返回一个observable的函数,然后我执行我需要对单个对象执行的操作。

注释掉的地图会按照我的预期正确打印所有单个对象。

然后我尝试将所有单个对象再次合并回一个数组(这似乎不起作用)。

如何将所有对象重新放回数组中? 并且大喊我使用任何其他类型的地图代替flatMap? (当我添加它而不是flatMap时,concatMap和mergeMap似乎都做了完全相同的事情)

〜修改

在使用下面的Picci答案之后,我把它改成了这个似乎运作得很好的。

this.groupChatsSub = CEChats.find({
    group: {$in: groupIds}
})
.mergeMap(listChats => {
    console.log('listy chats', listChats)
    let myArrayOfChats = [];
    let myArrayOfObservables = new Array<any>();
    for (let chat of listChats) {

        console.log('IN TEH FOR EACH');
        myArrayOfChats.push(chat);
        myArrayOfObservables.push(
            this.findLastChatMessage(chat._id, chat.lastMessage).map(lmsgsub=> {

                console.log('lmsgsub', lmsgsub)
                if(lmsgsub) {
                chat.lastMessage = lmsgsub;
                chat.unseen = !lmsgsub.seenBy.some((x)=>x==this.user._id);
                if(chat.unseen) {
                    this.groupChatUnseen++;
                }
                } else {
                chat.unseen = false;
                }
            });
        );
    };
    return Observable.combineLatest(myArrayOfObservables).map(()=> myArrayOfChats);
})

1 个答案:

答案 0 :(得分:1)

我假设最终你想拥有一个Observable,一旦所有findLastChatMessage被执行就会发出数组。

如果是这种情况,我会沿着这些方向尝试一些事情

this.groupChatsSub = CEChats.find({
    group: {$in: groupIds}
})
.mergeMap(list => {
   const myArrayOfChats = [];
   const myArrayOfObservables = new Array<Observables>();
   for (let chat of list) {
     myArrayOfObservables.push(this.findLastChatMessage(chat._id, chat.lastMessage).map(lmsgsub=> {
        myArrayOfChats.push(chat);
        console.log('lmsgsub', lmsgsub)
        if(lmsgsub) {
            chat.lastMessage = lmsgsub;
            chat.unseen = !lmsgsub.seenBy.some((x)=>x==this.user._id);
            if(chat.unseen) {
                this.groupChatUnseen++;
            }
        } else {
            chat.unseen = false;
        }
     });
     return Observable.combineLatest(myArrayOfObservables).map(() => myArrayOfChats);
   }
})

整个想法是创建一个Observables数组,然后通过combineLatest运算符获取一个Observable,它会在Observables数组中包含的所有Observable都发出后发出。

最后一个地图运算符用于返回聊天数组。

免责声明:我不完全确定代码是否正确,因为我没有构建真正的测试,只是简单地汇总了我认为相关的概念

PS:flatMap已重命名为mergeMap,因此2个运算符是相同的