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