在对对象进行操作时链接递归 RxJS 可观察对象
Posted
技术标签:
【中文标题】在对对象进行操作时链接递归 RxJS 可观察对象【英文标题】:Chaining recursive RxJS observables while operating on object 【发布时间】:2020-12-22 13:17:48 【问题描述】:我的后端有两个 graphql 查询:familiyTreeQuery
它返回一个家谱作为带有孩子的节点,它也可以有孩子等等,personPicturesQuery($name: string)
返回给定人的图片。
我的目标是调用familyTreeQuery
,迭代树,如果这个人叫Alice,那么我想为这个人调用personPicturesQuery
,并将信息添加到树中的节点。应该对树中的所有 Alice 都这样做。
我的问题是,获取图片的调用是异步发生的,因此在将信息添加到节点之前返回数据。
我未能按照this question 中的建议使用flatMap
,因为获取图片的调用是在迭代树时发生的,我无法在familyTreeQuery
的管道方法中调用它。
public getContext(): Observable<TreeNode>
return this.familyTreeQuery.watch().valueChanges.pipe(
map(result =>
const familyTree = result.data.familyTree;;
this.addPicturesToAlice(familyTree);
return familyTree;
)
)
private addPicturesToAlice(node: TreeNode)
if (node.name === 'Alice')
this.fetchPictures(node.id).subscribe(pictures =>
node.pictures = pictures;
)
if (node.children && node.children.length > 0)
for (const childNode of node.children)
this.addPicturesToAlice(childNode);
private this.fetchPictures(personId): Observable<Picture[]>
return this.personPicturesQuery.fetch(id: personId).pipe(
map(result =>
return result.data.personPictures;
)
)
据我了解,我不应该在 addPicturesToAlice
方法中调用 subscribe,但我是 Angular 和 RxJS 的新手,并没有找到一种方法来完成这项工作。
【问题讨论】:
structuredTrees
定义在哪里?
应该是familyTree
,编辑了问题
你可以考虑在这里从 Observable 切换到 Promise 并使用 async-await 方法。
如代码注释中所述,您可以假装它确实如此。我简化了问题的代码,实际上它处理其他东西
为了回答你的问题,理解它的作用是非常有必要的,所以我们可以重构addPicturesToAlice
【参考方案1】:
您可以通过创建一个 observables 数组并递归地传递它,然后使用 forkJoin
在 getContext
中订阅它来实现这一点,如下所示:
public getContext(): Observable<TreeNode>
return this.familyTreeQuery.watch().valueChanges.pipe(
switchMap(( data: familyTree ) => forkJoin(this.addPicturesToAlice(familyTree)))
)
private addPicturesToAlice(node: TreeNode, observables: Observable<Picture[]>[] = []): Observable<Picture[]>[]
if (node.name === 'Alice') observables.push(
this.fetchPictures(node.id).pipe(tap(pictures => node.pictures = pictures))
)
if (node.children?.length)
for (const childNode of node.children)
this.addPicturesToAlice(childNode, observables);
return observables;
private fetchPictures(personId: number): Observable<Picture[]>
return this.personPicturesQuery
.fetch( id: personId )
.pipe(map(result => result.data.personPictures))
希望它足够清楚。
【讨论】:
看来这样可以了,非常感谢!还有一个问题,如果familyTreeQuery
返回多个家族树,我该怎么办?在switchMap
之前我可以使用另一种 RxJS 方法吗?
请看看这个***.com/questions/42482705/…以上是关于在对对象进行操作时链接递归 RxJS 可观察对象的主要内容,如果未能解决你的问题,请参考以下文章
Angular RxJS入门笔记 (Observable可观察对象Subscribe订阅Observer观察者Subscription对象)
在 Angular 6 中使用 rxjs 可观察对象的目的是啥?与 async/await 相比,rxjs 的优势是啥? [复制]