当前位置: 首页 > 知识库问答 >
问题:

在对象上操作时链接递归RxJS观测值

焦学海
2023-03-14

我的后端有两个图形查询:famyTreeQuery,它返回一个家谱作为有孩子的节点,也可以有孩子等等,和人PicturesQuery($name: string),它返回给定人的图片。

我的目标是调用familyTreeQuery,迭代树,如果这个人被称为Alice,那么我想为这个人调用人PicturesQuery,并将信息添加到树中的节点。这应该为树上的所有爱丽丝做。

我的问题是,获取图片的调用是异步的,因此在信息添加到节点之前会返回数据。我没有按照这个问题中的建议使用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方法中调用订阅,但我是Angular和RxJS的新手,没有找到一种方法来实现这一点。

共有1个答案

苍宝
2023-03-14

您可以通过创建一个可观察的数组并递归传递它,然后使用forkJoingetContext中订阅它来实现这一点,如下所示:

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))
}

希望足够清楚。

 类似资料:
  • 我有2个API调用第二个调用使用第一个调用返回的东西。有了promise,这很容易: 我将如何使用可观测数据来实现这一点?

  • 我对RxJava很陌生,每当我有一个情况,我需要从链上的一个可观察的返回数据传递到调用“订阅” - 我很难理解如何在没有任何补丁的情况下以“反应式”方式做到这一点...... 例如: 我想发出obs1和obs2,得到它们的结果,然后发出obs3然后obs4,然后以订阅结束链,同时可以访问obs1、obs2、obs3和obs4的结果。 调用的顺序很重要,我需要在执行obs3之前完成obs1和obs2

  • 我正在使用RxJava链接异步操作,我想向下游传递一些变量: 这似乎是一种常见的模式,但我找不到有关它的信息。

  • 我有一个简单的api请求,它向一个对象返回一个可观察的对象,该对象中有一组项,每个项中都有一个链接。因此,我想在当前异步流中直接获取链接后面的数据,但我收到一个CORS错误,错误是: 这是否可能与我当前的函数?还是我误解了一些基本概念?

  • 我正在开发利用RxJava、realm和改进的应用程序。 我需要创建非常具体的数据处理链。我需要在io调度程序上执行改装调用,然后在我的自定义单线程领域调度程序上处理提供的数据,然后将结果推送到主线程调度程序上的ui。我试图通过使用多个组合来实现这一点,包括观察(observeOn)和订阅(subscribeOn),但我无法让中间部分在调度程序(scheduler)上执行。 我的目标是这样的

  • 在愉快地使用AngularJS 1之后,我目前正在尝试自学Angular2和打字脚本。*在过去的4年里!我不得不承认我讨厌它,但我确信我的尤里卡时刻就在眼前。。。无论如何,我已经在我的虚拟应用程序中编写了一个服务,它将从我编写的提供JSON服务的假后端获取http数据。 现在在一个组件中,我希望运行(或链)两个和方法。在AngularJS中,这很容易,因为在我的控制器中,我会做这样的事情来避免“末