如何解决使用Rxjs构建Angular Store
我有这个Angular应用,我想在其中创建聊天对象的自定义存储。
(代码和框:https://codesandbox.io/s/chat-store-yw4yz )
上下文
使其快速高效的想法是将两种类型的记录放入存储中:
- 带有
key = chat id
和value = chat object
的字典(作为地图) - 用于按 groupId 分组聊天的索引(作为地图),其中
key = groupId
和value = chatId
所以我有这个接口定义:
export interface ChatStoreModel {
chats: Map<number,Chat>;
chatsByGroup: Map<number,number[]>;
}
将聊天对象保存到应用商店中时,应该发生两件事:
- 聊天对象已保存到商店
chats
- 聊天ID被保存在相应的 groupId 中的存储区
chatsByGroup
中
问题
从群组中获取聊天对象不起作用。我执行以下操作:
代码:
getGroupChats$(groupId: number): Observable<Chat[]> {
return this._store.select("chatsByGroup").pipe(
map((chatsByGroup) => chatsByGroup.get(groupId) || []),switchMap((ids) => {
if (!ids || !ids.length) {
return of([]);
}
const chatsList$: Observable<Chat>[] = ids.map((id) =>
this._store.select("chats").pipe(map((chats) => chats.get(id)))
);
return forkJoin([...chatsList$]).pipe(
map((list) => {
return ([] as Chat[]).concat(...list);
})
);
}),shareReplay(1)
);
}
调试此代码后,它到达return forkJoin
行,并且id包含聊天列表,但它从未到达map((list) => {
行,因此该应用程序不会显示聊天列表。
任何帮助将不胜感激,谢谢!
解决方法
只要可观察的任何一项完成而不产生任何价值, forkJoin也会在那一刻完成,并且不会发出 都可以
这来自RxJS ForkJoin Doc。我的猜测是,您传递给forkJoin
的Observable之一没有发出任何东西而完成,因此forkJoin
立即完成了而没有发出任何东西。
请尝试使用defaultIfEmpty
运算符,以确保不会发生这种情况。我建议做这样的事情:
const chatsList$: Observable<Chat>[] = ids.map((id) =>
this._store.select("chats").pipe(map((chats) => chats.get(id))),defaultIfEmpty(null),);
forkJoin将等待所有传递的可观察值完成
这也是来自文档。这意味着您传递给forkJoin
的所有Observable必须完成,以使forkJoin
自身发出价值。
我的猜测是,this._store.select("chats").pipe(map((chats) => chats.get(id))),
这条线将无休止地运行,因此您需要提供take(1)
才能完成,否则forkJoin
将不会发出任何信息。所以尝试这样的事情:
const chatsList$: Observable<Chat>[] = ids.map((id) =>
this._store.select("chats").pipe(map((chats) => chats.get(id))),take(1),);
最后,如果您不想使用take(1)
,这意味着您想订阅Observable,只要它发出值,您可能想要使用combineLatest
而不是forkJoin
。这是因为forkJoin
等待完成发出某些东西,而combineLatest
将发出所提供的Observable的最新值。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。