【问题标题】:Merging observable back into an array将可观察对象合并回数组
【发布时间】:2017-06-19 05:12:59
【问题描述】:
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 处理传入的每个数组项,它调用另一个返回可观察对象的函数,然后我对单个对象执行我需要做的事情。

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

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

如何将所有对象重新放入数组中? 并喊我使用任何其他类型的地图来代替 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);
})

【问题讨论】:

    标签: angular observable


    【解决方案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,该 Observable 一旦包含在 Observables 数组中的所有 Observables 都发射完毕。

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

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

    PS:flatMap已经改名为mergeMap,所以2个操作符是一样的

    【讨论】:

    • 谢谢,正如您在免责声明中所说,我必须对其进行一些更改,但这绝对让我走上了正确的道路。再次感谢 :D 特别是关于 flatMap 和 mergeMap 的提示
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-11
    • 2018-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-09
    • 1970-01-01
    相关资源
    最近更新 更多