哪个运营商有条件地链接Observables?

时间:2017-08-09 15:16:32

标签: angular typescript rxjs

我想从REST API将一些分页的数据加载到我的Angular应用程序中。通常,API会按照以下结构向我发送数据:

{
    "next": null,
    "results": [
        {"id": 7, "name": "Alicia"},
        {"id": 8, "name": "Ted"},
        {"id": 9, "name": "Marshall"}
    ]
}

nextGET/下一个数据页请求的网址。显然,我事先并不知道我需要迭代以完全加载数据的页数。

我写了以下工作代码,以便完全获取数据(Working plunker here):

public loadPeople( next?:string ): void {
    if(!next) next = 'api/1.json';

    this.http.get(next)
        .map( (response: Response) => response.json() )
        .subscribe( (data: any) => {
            this._people = this._people.concat(data.results);
            this._peopleSubject.next(this._people);
            if(data.next) this.loadPeople(data.next);
        })
}

但是,我对Rx.JS缺乏经验,而且我非常确定通过使用运算符链接Observables来做更好,更清洁的方法,但我可以&# 39,把手放在上面。

我可以使用任何操作员的想法吗?谢谢 !

2 个答案:

答案 0 :(得分:2)

您可以使用concatMapconcat运营商:

public loadPage( next:string ): Observable<string[]> {
    return this.http.get(next)
        .map( (response: Response) => response.json() )
        .concatMap((data: any) => {
          if (data.next) {
            return Observable.of(data.results).concat(this.loadPage(data.next));
          }
          return Observable.of(data.results);
        });
}

public loadPeople( next?:string ): void {
    if(!next) next = 'api/1.json';

    this.loadPage(next)
        .subscribe( (people: string[]) => {
            this._people = this._people.concat(people);
            this._peopleSubject.next(this._people);
        })
}

您需要以下导入:

import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/concat';
import 'rxjs/add/operator/concatMap';

答案 1 :(得分:0)

您可以使用地图和订阅 MergeMap 。 地图和订阅将用作

this.http.get('/api/people/1')
  .map(res => res.json())
  .subscribe(character => {
    this.http.get(character.homeworld).subscribe(homeworld => {
      character.homeworld = homeworld;
      this.loadedCharacter = character;
    });
  });

}

但是这样我们可以注意到两件事

  • 首先,我们开始在嵌套中看到这个嵌套的金字塔结构 我们的Observables不太可读。

  • 第二个我们的两个请求是顺序的

因此我们可以使用mergemap映射/迭代Observable值,如

this.homeworld = this.http.get('/api/people/1')
  .map(res => res.json())
  .mergeMap(character => this.http.get(character.homeworld))

}

感谢** Cory Rylan **,他解释了这个enter link description here