微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

递归可观察调用不返回数据 常规递归使用流进行递归

如何解决递归可观察调用不返回数据 常规递归使用流进行递归

我需要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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?