Javascript 具有条件调用的可观察流

Javascript 具有条件调用的可观察流,javascript,angular,rxjs,observable,Javascript,Angular,Rxjs,Observable,我有一个可观察的流,它在使用在对象中找到的两个id检索初始对象之后进行两次调用。其中一个id是可选的,可能存在也可能不存在。siteId是可选id。如果找到它,我必须像调用getTeam一样调用它。如何进行有条件呼叫?我能够让它工作的唯一方法是在subscribe方法中检查id并从那里调用。但是,代码将有嵌套的订阅,这是我想要避免的 private getZone() { this.spinner.show(); this.zonesService.getZone(this.z

我有一个可观察的流,它在使用在对象中找到的两个id检索初始对象之后进行两次调用。其中一个id是可选的,可能存在也可能不存在。siteId是可选id。如果找到它,我必须像调用getTeam一样调用它。如何进行有条件呼叫?我能够让它工作的唯一方法是在subscribe方法中检查id并从那里调用。但是,代码将有嵌套的订阅,这是我想要避免的

private getZone() {
    this.spinner.show();

    this.zonesService.getZone(this.zoneId)
      .map(response => {
        this.zone = response['group'];
        this.teamId = this.zone['TeamId'];
        this.siteId = this.zone['SiteId'];
        return this.zone;
      })
      .flatMap(() => this.teamsService.getTeam(this.teamId))
      .map(response => {
        if (response['team']) {
          this.team = response['team'];
          if (this.team['personal']) { this.team['name'] = 'Personal Team'; }
          this.zone['teamName'] = this.team['name'];
        }
        return response;
      })
      .subscribe(
        _data => {
          if (this.zone['personal']) { this.zone['name'] = 'My Personal Zone'; }
          if (this.siteId) {
            this.sitesService.getSite(this.siteId)
              .subscribe(
                _data => {
                  this.site = _data['site'];
                }
              );
          }

          this.spinner.hide();
          this.loading = false;
        }
      );
  }

任何帮助都将不胜感激。谢谢。

如果我没说错,您已经获得了第一次调用(zonesService.getZone)时需要使用的所有值。如果您在此时分割流(可能共享),并对其他两个端点进行单独调用,您可以并行处理这两个端点,并对sitesService.getSite使用“null”可观察值(defaultIfEmpty操作符)最后,使用zip函数再次合并em。

您可以在第一个flatMap()中使用forkJoin()方法

因此,从功能上讲,您进行了初始api调用。然后,如果该响应返回站点id,则并行进行团队和站点调用,否则进行单个团队调用


这里有一个关于forkJoin的好资源:

谢谢。我只是在学习RXJS。由于我的工作是如此的涉及到额外的责任在这个时候做前端和后端,我没有时间真正进入文档。你的解决方案可能很棒。虽然我试过了,但我没有足够的背景知识来编写代码。我真的很想从你的建议中学习。如果您有时间添加一个代码示例,那将很酷。
this.zonesService.getZone(this.zoneId)
    .flatMap(response => {
        this.zone = response['group']

        if(this.zone.SiteId){
            // make these 2 api calls in parallel
            return Observable.forkJoin(
                this.getTeam(this.zone.TeamId),
                this.getSite(this.zone.SiteId)
            );
        }else{
            // make single api call
            return this.getTeam(this.zone.TeamId);
        }
    }).subscribe(response => {
        // note that your response will be different based on the flatMap(). 
        // When you do the 2 calls in parallel, your response = [getTeamResponse, getSiteResponse]
        // but when you just do the single call, your response = getTeamResponse
        // so you'll need a check in here to account for that
    });