创建递归的Observable循环?

时间:2018-06-06 06:59:03

标签: rxjs angular2-observables

我很难搞清楚如何使用Observables为api调用创建一个递归循环。

方案: 我调用外部API,返回类似这样的内容:

Array.prototype.duplicate = function () {
  this.splice(0,0, ...this);
}

const a = [1, 2, 3, 4, 5];

a.duplicate();
console.log(a);

只要响应在{ data: {something, something, something}, next: "url for next set of data" } 中有值,我就需要继续调用相同的函数将所有数据收集到一个对象中。

我设法在另一个使用Promises的项目上执行此操作,我使用next函数将返回的数据映射到单个数组中,但我无法理解如何使用{{1}执行此操作}。

使用promises的工作示例:

concat()

3 个答案:

答案 0 :(得分:2)

您可以使用.expand()运算符。此递归的终止条件是next属性为falsy时。使用三元运算符,代码只是一个线程:

expand(({data, next}) => next ? getData(next): Observable.empty() )
    .subscribe(result => console.log(result));

这是工作JSBin。我嘲笑了很多东西,但它应该是非常简单的。

答案 1 :(得分:0)

结束对我有用的解决方案:

let obs = this.getData(endpoint, options).pipe(
  expand(({ next }) => {
    // This could be oneliner but I had to alter options for the calls after the first one for my own case
    return next ? this.getData(next, options) : Observable.empty()
  }),
  concatMap(({data}) => data)
)

obs.subscribe(
  data => mapthedata(data),
  error => error,
  complete => {
    // do something with the mapped data
  }
)
function mapthedata(data) {
  // here you should combine the data results into one, f.ex pushing to local variable
}

答案 2 :(得分:0)

今天刚遇到这个类似的问题,这是我的尝试。我认为困难的部分是正确思考您要实现的目标,然后找到支持该目标的正确运算符。

在这种情况下,从第一个 observable 开始,我们希望 expand 并继续递归地发出值直到完成。最后我们想要收集的是这个 observable 发出的所有值,那时我搜索了正确的关键字并找到了 toArray 来支持这种情况。

参考:How to collect array of emitted values from Observable.from?

this.getData(endpoint, options).pipe(
  expand(({ next }) => {
    return next ? this.getData(next, options) : Observable.empty()
  }),
  toArray(), // wait for the observable to complete and collect all emitted values
)