使用多个有序的异步服务

Working with multiple ordered async services

我的组件中注入了多项服务。其中两个提供了为我的第三个服务查找项目所需的对象列表。我的问题是对它们的异步调用并不总是有序的。将调用彼此嵌套似乎并非在所有情况下都有效,而且无论如何嵌套它们都不会成功。我如何强制我的服务加载它们的所有值以便我可以使用它们?我尝试将我的服务放在我的构造函数中并加载它们的响应,然后尝试在 ngOnInit() 中调用这些响应,但这也不起作用。

打字稿

 constructor(     
    private stateService: StatesService, 
    private zoneService: ZoneDetailService, 
    private countyService: CountyService) { 

      //gather states from service
      this.stateService.GetStates().subscribe(response => {
        this.statesResults = response;
        //do something with response
       });

      //gather counties from service
      this.countyService.GetCounties().subscribe(response => {
        this.countyResults = response;       

          //gather detail from service
          this.zoneService.GetZoneDetails(this.prodPointId).subscribe(response => { 

            this.state = response.stateCode;                
            this.apiCountyCode = response.apiCountyCode;              

            //return single record
            let answer = this.countyResults.filter(c => c.countyCode === response.apiCountyCode).map(c => {
              return c.id;
            });

            let answer2 = this.statesResults.filter(c => c.stateCode === response.stateCode).map(c => {
              return c.id;
            });

如图所示,stateService 不加载 stateResults,因此它保留为 'undefined',然后过滤器不起作用。我需要确保我的 stateService 和 countyService 在我的 detailService 之前都是 运行。任何帮助,将不胜感激。谢谢。

有很多方法可以做到这一点,但是 forkJoin 可以在这里工作。 ForkJoin 接受一组可观察对象,并在它们全部完成时完成。所以:

import {forkJoin} from 'rxjs';
import {map} from 'rxjs/operators';
forkJoin([this.statesService.getStates(), this.countyService.getCounties(), this.zoneService.GetZoneDetails(this.prodPointId)])
    .subscribe(res => {
        // res[0] would be the result of getStates
        // res[1] would be the result of getCounties
})

不过我会提醒您,我发现在服务中订阅可观察对象通常是一种糟糕的代码味道。我通常尝试只订阅组件内部的可观察对象,并在服务中的 rxjs 函数中执行我的所有逻辑。

您好,您可以同时执行所有可观察对象并使用 Observable.forkJoin() 等待结果 让我举个例子:

const queries: Observable<any>[] = [];

queries.push(this.countyService.GetCounties());
queries.push(this.stateService.GetStates());          
queries.push(this.zoneService.GetZoneDetails(this.prodPointId));

Observable.forkJoin(queries)
  .take(1)
  .subscribe(data => { 
     this.countyResults = data[0]
     this.statesResults = data[1]
     this.zoneDetails = data[2]
  }

希望对您有所帮助