摘要:本质上,我需要类似from Users where usergroupIds in [1,3,5]
的东西。
给出usergroupIds$
发出一组ID为[1,3,5]
的数组
我想通过userids
中的usergroupIds
合并所有用户,并合并userIds(不同)
这是我想出的:
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$
似乎是错误的?
是否可以在RxJS中完全表达users$
,而不必每次都在预订中创建它?
更新: 在@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]]
之类的东西,我不介意在subscription上执行额外的处理:
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
运算符?
答案 0 :(得分:1)
看看是否可行。基本上,它会在usergroupIds $发出时触发,因此您可以观察到新的动态。如果您始终希望源可观察的shareReplay
在订阅时发出最后保存的值,则需要usergroupdIds$
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)
)
})
)
答案 1 :(得分:0)
因此,您不想每次createUsersObservable
发出时都单独向usergroupIds$
发出请求。听起来mergeScan
是一个很好的用例:
usergroupIds$.pipe(
mergeScan((users, user) => createUsersObservable().pipe(
map(user => [user, ...users]),
), []),
);