Rxjs 创建递归可观察循环?

Rxjs 创建递归可观察循环?,rxjs,angular2-observables,Rxjs,Angular2 Observables,我很难弄清楚如何创建一个递归循环,以使用可观察的api调用 情景: 我调用外部API,它返回如下内容: { data: {something, something, something}, next: "url for next set of data" } 我需要继续调用相同的函数来将所有数据收集到一个对象中,只要响应在下一个中有值 我设法在另一个项目上做到了这一点,并承诺通过使用concat()函数将返回的数据映射到单个数组中,但不知何故,我无法理解如何使用可观察对象来实现这一点 使用

我很难弄清楚如何创建一个递归循环,以使用可观察的api调用

情景: 我调用外部API,它返回如下内容:

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

我设法在另一个项目上做到了这一点,并承诺通过使用
concat()
函数将返回的数据映射到单个数组中,但不知何故,我无法理解如何使用
可观察对象来实现这一点

使用承诺的工作示例:

getData: function(url, params, headers){
    return new Promise((resolve, reject) => {
        axios.get(url, {
            params: params,
            headers: headers,
        }).then((response) => {
            let responseData = response.data.data[0];
            if (response.data.next) {
                this.getData(response.data.next, {}).then((resp) => {
                    for (let dataSet of responseData.dataSets) {
                        let row = resp.dataSets.find(i => i.variable === dataSet.variable)
                        if (row) {
                            dataSet.data = dataSet.data.concat(row.data)
                        }
                    }
                    resolve(responseData);
                }).catch((error) => {
                    reject(error)
                })

            } else {
                resolve(responseData);
            }
        }).catch(error => {
            reject(error)
        })
    })
}

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

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

这是工作表。我嘲弄了很多东西,但这应该是很琐碎的。

对我有效的最终解决方案:

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
}

今天我遇到了类似的问题,下面是我的尝试。我认为困难的部分是正确地思考您试图实现的目标,然后找到正确的操作员来支持它

在本例中,从第一个可观察到的值开始,我们希望
展开该值,并继续递归地发出值,直到完成为止。我们想在最后收集的是这个可观察到的所有发出的值,那时我搜索了正确的关键字,找到了
toArray
来支持这个例子

参考:


你可以在这里发布你的代码,就像你承诺的那样。编辑问题以包括示例非常有帮助,我让电话正常工作,而且很容易阅读。我唯一不太明白的部分是如何映射数据,concatMap本身并不能解决这个问题,因为我只想在数据集中映射数据。。。对不起,我今天过得太慢了。。。
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
)