首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >需要进行多个HTTP调用并合并结果

需要进行多个HTTP调用并合并结果
EN

Stack Overflow用户
提问于 2018-06-19 21:52:42
回答 1查看 8.2K关注 0票数 2

我有一个问题,考虑到我对角(v6.0),RxJs (v6.0)和一般的可观测数据缺乏经验,在过去的一周里引起了一些相当大的头痛。

组件使用的服务需要输出数据模型集合,但要这样做需要四个单独的api调用,而且我遇到了相关数据的问题,这是可选的,停止数据模型的返回。

Basic flow

  • 第一个api调用获取主实体并创建初始数据模型集合。
  • 第二个api调用将获取相关数据并将其添加到数据模型中。
  • 第三个api调用将获取相关数据(如果存在),并将其添加到数据模型中。
  • 第四个api调用将从第三个api调用中获取与最近一个相关条目相关的数据。然后返回数据模型收集。

设计

  • 对于第二次、第三次和第四次api调用,使用基于an ID集合的批处理查询方法来减少调用的次数,这是可以的,因为我们一次只请求10、20条记录。

Expectations

  • 如果没有从第一个api调用返回的主要实体,则不会发生以下所有调用。
  • 第二个api调用将始终返回数据。
  • 如果第三个api调用没有返回任何相关数据,这不是问题,但是应该返回数据模型集合。
  • 如果第三个api调用没有返回相关数据,则不会发生第四个api调用,但是应该返回数据模型集合。

发行

  • 确保在没有为第三次和第四次api调用找到结果时返回数据模型收集。
  • 我不能改变api。

已知

  • 我没有太多的错误处理方法。
  • 很可能有很多错误,抱歉。
  • 这是一条很长的链子,最好把它分成小块。
  • 我对JavaScript的经验是生疏的。

尝试过

  • 我已经广泛地研究了'*map‘函数和'forkJoin’,但是没有能够使任何东西正常工作,使用RxJ时,大多数示例都是针对小于6.0版本的,因此很难翻译。

我想把它缩短一些,但是我们调用api的方式在这里是很重要的。

代码语言:javascript
复制
return this.agentService.GetByFilter(query)
  .pipe(
    map(agents => {
      let deployments : AgentDeployment[] = [];

      for(let i = 0; i < agents.length; ++i) {          
        deployments.push(new AgentDeployment(agents[i].id, agents[i].name, agents[i].tags));
      };

      return deployments;
    }),
    map(deployments => {
      // Getting related tags assoiciated with the agent

      let tagIds : Array<number> = [];

      // Get tag id's
      for(let i = 0; i < deployments.length; ++i) {          
        if (deployments[i].tagIds) {
          for(let y = 0; y < deployments[i].tagIds.length; ++y) {
            if (!tagIds.includes(deployments[i].tagIds[y])) {
              tagIds.push(deployments[i].tagIds[y]);
            }              
          };
        }
      }

      // Get the tags associated with the agents
      let filter = new Filter();
      filter.Field = 'ID';
      filter.Value = tagIds.join(',');

      // Get tags using list of tag id's
      return this.tagService.GetByFilter(filter).pipe(
        map(tags => {        
          if (tags.length) {
            for(let i = 0; i < tags.length; ++i) {     
              // Find the agent
              deployments.forEach(deployment => {
                if (deployment.tagIds && deployment.tagIds.includes(tags[i].id)) {
                  deployment.tags.push(tags[i]);
                }
              });
            }              
          }
          return deployments;
        }));
    }),
    mergeMap(deployments => deployments),
    map(deployments => {
      // Getting deployments related to the agent, an agent may not have any deployment packages associated

      let agentIds : Array<number> = [];

      // Get tags
      for(let i = 0; i < deployments.length; ++i) {          
        if (deployments[i].id) {
            agentIds.push(deployments[i].id);
        }
      }

      // Get the deployment packages for the agents
      let filter = new Filter();
      filter.Field = 'AgentId';
      filter.Value = agentIds.join(',');

      // Get agent deployment packages using list of agent id's
      return this.agentDeploymentPkgService.GetByFilter(filter)
        .mergeMap(packages =>  packages)
        .groupBy(pkg => pkg.id)            
        .map(pkg$ => {
          if (pkg$) {
            // Add packages to agent deployment
            pkg$.map(pkg => {
            // Find the agent
            let i : number = deployments.findIndex(agent => agent.id == pkg$.key);

              if (pkg.deploymentPackageIds) {
                // Keep last deployment ID handy
                deployments[i].lastDeploymentId = Math.max.apply(null, pkg.deploymentPackageIds);;
                deployments[i].deployments.push(new Deployment(pkg.id, pkg.name))
              }
            }); 
          }
          return deployments;
        });
    }),
    mergeMap(deployments => deployments),
    map(deployments => {
      // Get the logs for the most recent deployment package for the agent, may not exist if no recent deployment package

      let deploymentPackageIds : Array<number> = [];

      // Get tags
      for(let i = 0; i < deployments.length; ++i) {          
        if (deployments[i].id) {
          deploymentPackageIds.push(deployments[i].lastDeploymentId);
        }
      }

      // Get the deployment packages for the agents
      let filter = new Filter();
      filter.Field = 'DeploymentPackageId';
      filter.Value = deploymentPackageIds.join(',');

      // Get agent deployment log based on the last 
      this.logService.GetByFilter(filter)
        .map(logs => {
          logs.forEach(log => {
            // Find the agent
            let i : number = deployments.findIndex(agent => agent.lastDeploymentId == log.deploymentPackageId);

            deployments[i].logId = log.id;
            deployments[i].status = log.lastReportedStatusMessage;
          });

          return deployments;
        });


      return deployments;
    })
  );
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-09 14:50:02

这里的快速答案是

代码语言:javascript
复制
forkJoin

检查文件

Rxjs - ForkJoin

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50937426

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档