递归Observable调用不返回任何数据



我需要RxJS专业人士的帮助:(

我尝试通过http请求从RESTneneneba API递归加载数据。递归调用运行良好,但是当我订阅最终的Observable(由GetTemperatures返回(时,订阅中不会返回任何数据。

呼叫链中似乎没有返回任何数据。

这里出了什么问题?

GetTemperatures().subscribe((data: MeasureData) => {
// add data to a chart, etc...
})
GetTemperatures(): Observable<MeasureData> {
const l_startDate = new Date(2019, 0, 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', this._deviceId)
.set('module_id', this._moduleId)
.set('scale', '1hour')
.set('type', 'Temperature')
.set('date_begin', Math.floor(data.value[data.value.length - 1].date.getTime() / 1000).toString())
.set('real_time', 'true')
.set('optimize', 'true');
return this._http.post<MeasureDataInternal>(this._getMeasureUrl, 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, l_httpParams)
.pipe(
map((data: MeasureDataInternal): MeasureData => 
this.transformMeasureData(data)
),
mergeMap((data: MeasureData) => 
merge (
of(data),
this.recursiveLoadData(data)
)
)
);

最新更新