我希望在Angular2中的第一个调用之后调用两个observable

时间:2017-10-14 19:53:31

标签: angular rxjs observable angular2-observables

我想调用两个observable,第二个调用后调用第二个。

我有一个也是首先订阅的观察者。 然后我希望第二个observable嵌套在第一个observable中。

我想将以下两个订阅结合起来:

this.serviceA.getData()
.takeUntil(destroyed$)
.subscribe(item => {

});

this.serviceB.getData()
.takeUntil(destroyed$)
.subscribe(item => {

});

这是我尝试展示我想做的事情(已更新)

  destroyed$: Subject<any> = new Subject<any>();

  ngOnInit(): void {
    this.serviceA.getData
      .takeUntil(this.destroyed$)
      .concatMap(dataA => {
        this.myDataA= dataA;    

        return this.serviceB.getData;
      })
      .takeUntil(this.destroyed$)
      .subscribe(dataB => {            

         this.myDataA.forEach(item => {
             item.visible = dataB.find(o => o.id === item.label).isVisible;
         }); 

      });
  };

  ngOnDestroy(): void {
    this.destroyed$.next(true);
    this.destroyed$.complete();
  };

目标是在第一次订阅后让嵌套订阅名为second,因为第二次订阅中第一个订阅者需要数据

2 个答案:

答案 0 :(得分:3)

好问题(Y),

您需要使用forkJoin docs

  

在(并行)中运行所有可观察序列并收集它们的最后元素。

示例:

let character = this.http.get('https://swapi.co/api/people/1').map(res => res.json());
let characterHomeworld = this.http.get('http://swapi.co/api/planets/1').map(res => res.json());

Observable.forkJoin([character, characterHomeworld]).subscribe(results => {
  // results[0] is our character
  // results[1] is our character homeworld
  results[0].homeworld = results[1];
  this.loadedCharacter = results[0];
});

参考:https://coryrylan.com/blog/angular-multiple-http-requests-with-rxjs

因此,根据您的具体情况,您可以执行以下操作:

let obs1 = this.serviceA.getData()
let obs2 = this.serviceB.getData()

Observable.forkJoin([obs1, obs2]).subscribe(results => {
  // results[0] is our obs1
  // results[1] is our obs2
  // show the bigger array
  this.items = results[0] > results[1] ? results[0] : results[1]
});

但是如果你需要一些依赖于另一个的数据,你可以做一些像

这样的事情

showData() {
  let firstData;
  this.serviceA.getData()
    .map((firstNeededData) => {
      firstData = firstNeededData
      return this.serviceB.getData()
    })
    .subscribe(secondNeededData => {
      // I need to show the bigger 
      this.theBigger = secondNeededData > firstData ? secondNeededData : firstData
    })

}

答案 1 :(得分:2)

接受的答案不正确。 forkJoin将同时订阅两个Observable,同时您希望首先订阅第一个Observable并在完成订阅第二个Observable之后订阅。

这通常使用concatMap运算符完成:

this.serviceA.getData()
  .concatMap(response => this.serviceB.getData())
  .subscribe(...)

如果要合并这两个回复,请在map之后使用serviceB.getData()

this.serviceA.getData()
  .concatMap(responseA => this.serviceB.getData()
    .map(responseB => /* combine responseA and responseB */ ))
  .subscribe(...)