在 angular2 中使用 Rxjs 连接分页响应

Concat paginated response using Rxjs in angular2

我正在从 angular2 应用调用外部 API,它以分页形式提供数据。响应看起来像这样

{
   next: "next_url",
   results: []
}

我可以使用 Rxjs 或 Angular2 的内置 Http class 来连接下一个 url 到

的结果吗?returns
{
   next: null,
   results: []
}

我觉得我需要使用 concatMap 运算符,但我还没有弄清楚语法,因为我是 Reactive Extentions 的新手。

我会这样做:

import {Component} from 'angular2/core';
import {Observable} from 'rxjs/Observable';
import 'rxjs/Rx';

@Component({
  selector: 'my-app',
  template: `<h2>Results: {{out | async | json}}</h2>`,
})
export class App {
  constructor() { 
    this.out = this.getAllResults();
  }

  getAllResults(startIdx = 0) {
    return this.getData(startIdx)
      .concatMap(data => {
        if (data.next) {
          return this.getAllResults(data.next)
            .map(resultsToJoin => [...data.results, ...resultsToJoin]);
        } else {
          return Observable.of(data.results);
        }
      });
  }

  // pretend this is our http call 
  getData(idx : number) {
    const data = [{
        next: 1,
        results: [1, 2]
      }, {
        next: 2,
        results: [3, 4]
      }, {
        next: null,
        results: [5, 6]
    }];

    return Observable.of(data[idx]);
  } 
}

http://plnkr.co/edit/7r4TaW

只是为了替代解决方案,这个也有效

getAllResults(startIdx = 0) {
  return this.getData(startIdx)
    .expand(data => {
      return data.next ? this.getData(data.next) : Observable.empty()
    }).scan((acc, data) => {
      return [...acc, ...data.results]
    }, []);

}

expand 运算符递归调用内部可观察对象。如果没有 scan 运算符,它会不断发出每个页面的数据。使用scan将每页的数据缩减为单个结果数组。

注意:这不是我一直在寻找的解决方案。因为它将每个页面结果作为数组发出,而不仅仅是最终数组。但是发现这些有用的运算符很有趣。

http://plnkr.co/edit/vrZEywkeys6sa5Nsccbg?p=preview