如何解决递归可观察调用不返回数据 常规递归使用流进行递归
我需要RxJS专业人员的帮助:)
我尝试通过http请求从REST API递归加载数据。 递归调用工作正常,但是当我怀疑使用最终的Observable(由GetTemperatures返回)时,订阅中没有返回任何数据。
似乎没有数据在调用链中传回。
这是怎么了?
GetTemperatures().subscribe((data: MeasureData) => {
// add data to a chart,etc...
})
GetTemperatures(): Observable<MeasureData> {
const l_startDate = new Date(2019,1);
var l_httpParams = new HttpParams()
.set('device_id',this._deviceid)
.set('module_id',this._moduleId)
.set('scale','1hour')
.set('type','Temperature')
.set('date_begin',Math.floor(l_startDate.getTime() / 1000).toString())
.set('real_time','true')
.set('optimize','true');
return this._http.post<MeasureDataInternal>(this._getMeasureUrl,l_httpParams)
.pipe(
map((data: MeasureDataInternal): MeasureData => this.transformMeasureData(data)),flatMap((data: MeasureData) => {
return this.recursiveLoadData(data);
})
);
}
recursiveLoadData(data: MeasureData): Observable<MeasureData> {
// search until Now minus 1,5 hours
const endDate = new Date(Date.Now() - (1.5 * 60 * 60 * 1000));
console.error('RECURSIVE begin: ' + data.value[0].date + ' end: ' + data.value[data.value.length - 1].date);
// check if complete
if (data.value[data.value.length - 1].date.getTime() >= endDate.getTime()) {
console.error('recursive ENDs here');
return EMPTY;
}
var l_httpParams = new HttpParams()
.set('device_id',Math.floor(data.value[data.value.length - 1].date.getTime() / 1000).toString())
.set('real_time',l_httpParams)
.pipe(
map((data2: MeasureDataInternal): MeasureData => this.transformMeasureData(data2)),flatMap((data2: MeasureData) => {
return this.recursiveLoadData(data2);
})
)
}
解决方法
我不知道,您实际上是想完成什么,但是递归中的每个新步骤除了将您带到下一步之外,没有任何其他作用。因此,您需要包括希望每个步骤执行的操作。
这不是特定于流的,一般递归也是如此。
常规递归
这与常规递归函数的工作原理没有任何不同。假设您要递归地将数组中的数字相加,则需要将数组的尾部添加到第一个值。如果您只是继续在较小的数组上递归而不加总弹出的数字,那么您将获得基本情况的值。
这将返回数组的最后一个值(数组的最后一个值是基本情况):
recursiveAdd(array){
if(array.length === 1) return array[0];
return recursiveAdd(array.shift());
}
这将添加数组:
recursiveAdd(array){
if(array.length === 1) return array[0];
return array[0] + recursiveAdd(array.shift());
}
在这种简单情况下,+
操作数在递归的每个步骤中都在执行工作。没有它,该数组将无法汇总。而且,我当然可以做任何事情。从1000中减去该数组,对数组中的数字求平均值,然后从这些值中构建一个对象。 任何内容。
在进行递归调用之前,您必须做一些事情。除非您追求的是基本情况的价值(在您的情况下为空流)
使用流进行递归
将值合并映射到流中时,不会同时转发该值。
from([69,70,71]).pipe(
mergeMap(val => from([
String.fromCharCode(val),String.fromCharCode(val),String.fromCharCode(val)
]))
).subscribe(console.log);
输出
e e e f f f g g g
注意输出中不包含任何数字吗? mergeMap
时,您将值映射到流中。如果要映射的值成为流的一部分,则必须以某种方式包括它们。这与常规递归相同。
因此,这里有两个示例,都将您的数据包含在返回的流中。它们是非常基础的,但是希望您可以从中获得一些理解并将其应用。
这将转换返回的流以将您的数据作为其第一个值(当然是递归的)
return this._http.post<MeasureDataInternal>(this._getMeasureUrl,l_httpParams)
.pipe(
map((data: MeasureDataInternal): MeasureData =>
this.transformMeasureData(data)
),mergeMap((data: MeasureData) =>
this.recursiveLoadData(data).pipe(
startWith(data)
)
)
);
这将创建数据流,递归调用流,并将两个流合并在一起。
return this._http.post<MeasureDataInternal>(this._getMeasureUrl,mergeMap((data: MeasureData) =>
merge (
of(data),this.recursiveLoadData(data)
)
)
);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。