1

摘要:本质上我需要类似from Users where usergroupIds in [1,3,5].

给定usergroupIds$发出一组组 ID[1,3,5]

我想通过useridsin联合所有用户usergroupIds并组合 userIds (distinct)

这是我想出的:

usergroupIds$.subscribe(usergroupIds => {
    const users$s = usergroupIds.map(gid => createUsersObservable(gid))
    //  [users$ in group 1, users$ in group 3, users$ in group 5]
    const users$ = combineLatest(...user$s).pipe(
        distinct(user => user.id)
    )
})

createUsersObservable = gid => 
  collectionData(db.collection('users').where('groupId', '==', gid)) // rxFire firestore

users$每次更改时退订和重新订阅似乎是错误的?

是否可以users$在不每次都在订阅中创建它的情况下在 RxJS 中完全表达?

更新: 在@FanCheung 的帮助下:

combinedUsers$ = userGroupIds$.pipe(
        switchMap(userGroupIds => {
            const users$s = userGroupIds.map(groupId =>
                createUsersObservable(groupId))
            return combineLatest(...users$s)
        })

但是,由于 usersObservable 一次发出一组用户,因此 combineUsers$ 会产生类似的结果[[userA, userB], [userB, userC], [userA, userD]],我不介意对订阅进行额外处理:

combinedUsers$.subscribe(combinedUsers => {
        const userMap = {}
        for (const users of combinedUsers) 
            users.forEach(user => (userMap[user.id] = user))
        const uniqueUsers = Object.values(userMap)

        // update UI to uniqueUsers
    })

但是,有没有办法以某种方式将 的结果展平combinedUsers$,然后执行distinct运算符?

4

2 回答 2

1

看看这是否有效。基本上它会在 usergroupIds$ 发出时触发,从而获得新的动态 observable。shareReplay如果您总是希望源 observableusergroupdIds$在订阅时发出最后保存的值,则需要

usergroupIds$.pipe(
shareReplay(1),
switchMap(usergroupIds => {
    const users$Array = usergroupIds.map(gid => createUsersObservable(gid))
    //  [users$ in group 1, users$ in group 3, users$ in group 5]
   return forkJoin(...users$Array).pipe(
        map(arr=>[].concat(...arr)),
        switchMap(arr=>from(arr)),
        distinct(user => user.id)
    )
})
)
于 2019-01-15T02:05:21.857 回答
0

所以你不想createUsersObservable每次usergroupIds$发出单独的请求。这听起来像是一个很好的用例mergeScan

usergroupIds$.pipe(
  mergeScan((users, user) => createUsersObservable().pipe(
    map(user => [user, ...users]),
  ), []),
);

现场演示:https ://stackblitz.com/edit/rxjs-8zybdu

于 2019-01-15T10:36:08.433 回答