哪个运算符有条件地链接 Observables?

Ale*_*ues 5 rxjs typescript angular

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

{
    "next": null,
    "results": [
        {"id": 7, "name": "Alicia"},
        {"id": 8, "name": "Ted"},
        {"id": 9, "name": "Marshall"}
    ]
}
Run Code Online (Sandbox Code Playgroud)

哪里next是下一个数据页请求的 url GET/。显然,我事先并不知道需要迭代多少页才能完全加载数据。

我编写了以下工作代码以便完全获取数据(此处为工作plunker):

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

    this.http.get(next)
        .pipe(
          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);
        })
}
Run Code Online (Sandbox Code Playgroud)

然而,我确实缺乏 Rx.JS 的经验,并且我很确定有一种更好、更干净的方法来做到这一点,通过Observables使用运算符进行链接,但我无法亲自动手。

我可以使用一个运算符吗?谢谢 !

Joe*_*oel 5

您可以使用concatMap和concat运算符:

public loadPage( next:string ): Observable<string[]> {
    return this.http.get(next)
        .pipe(
          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);
        })
}
Run Code Online (Sandbox Code Playgroud)

您将需要以下导入:

import { of } from 'rxjs'
import { concat, concatMap,  map } from 'rxjs/operators';
Run Code Online (Sandbox Code Playgroud)