【问题标题】:RxJS asynchronous loopRxJS 异步循环
【发布时间】:2016-10-26 16:25:04
【问题描述】:

我们正在做一些原型测试,我们通过 http 获取大约 28000 条记录的 json。我们将其转换为 Typescript 中类的实例,并将其添加到现有数组中。

然后将数组绑定到重新显示列表的视图。

this.http.get("http://localhost:8100/list.son")
            .map((res) => res.json())
            .flatMap((array, index) => array).
            .subscribe((value:any) => {
                    console.log("RENDERING");
                    this.list.push(new Element(8, value.name, value.number));
                  });

问题在于 flatmap 似乎将数组的元素一个一个地同步传递给 subscribe 函数(尝试在 http 调用之前使用设置的超时,它只在订阅之后运行)。因此,它是一种 28000 个元素的循环,它会挂起 UI 线程。我们如何在间隔的基础上触发订阅,以便 UI 线程可以在处理列表元素期间获得一些时间。 (本质上是伪异步递归)。

编辑:用 Meir 的回答更新代码

这是我目前拥有的代码,另外我认为 map 是错误的操作,因为它输出了它接受的输入数量。所以如果我错了,请纠正我,它接受一个 http 响应并输出一个数组,并且因此,该数组由其余步骤作为一个整体进行处理。此外,我还提供了示例 list.json。

this.http.get("http://localhost:8100/list.json")
                .map((res) => {
                  console.log(res.json().list);
                  return res.json().list
                })
                .delayWhen((v) => Observable.timer(50))
                .buffer(Observable.timer(50, 50))
                .subscribe((entry) => {
                  console.log("CAME HERE AA " + entry);
                });

LIST JSON,还有更多条目,但我在这里只保留了两个

{ "list" : [
  {
    "name" : "test",
    "number" : "that",
    "verificationId" : 78
  },
  {
    "name" : "test",
    "number" : "that",
    "verificationId" : 78
  },
  {
    "name" : "test",
    "number" : "that",
    "verificationId" : 78
  },
  {
    "name" : "test",
    "number" : "that",
    "verificationId" : 78
  }]
}

【问题讨论】:

  • 为什么要使用flatMap而不是简单的地图?

标签: javascript arrays asynchronous angular rxjs


【解决方案1】:

您可以按块大小或时间对其进行分块,对于时间块使用:

source.buffer(Rx.Observable.timer(250, 250))
   .subscribe(chunk => {
     console.log('chunk ', chunk);
     list1.splice(list1.length, 0, ...chunk);
});

jsbin sample 在这两种情况下都能正常工作。

【讨论】:

  • 快到了,只是坚持了一件事。将它与 http 调用一起使用时,我如何处理响应,将其转换为 json 数组并将其传递给 delayWhen 以进行分块。我尝试简单地将 "this.http.get("localhost:8100/list.son") .map((res) => res.json())" 添加到您的示例中,但当时还没有订阅
  • 你能发布完整的代码吗?我怀疑您的 http 调用在其结束时没有订阅,所以它保持冷态。一般情况下:this.http.get(...).map(...).subscribe(...)
  • 用代码示例更新了主要问题。在这里达到了订阅(我不记得它是冷的,因为我改变了很多),但是条目为空,并且在 console.log 中没有打印任何内容
  • 为什么需要 flatMap?
  • 使用 flatmap 以便根据 json 返回的数组中元素的数量调用订阅,因此无需循环我就可以处理数组,因此当有 200 个元素时,订阅将被调用 200 次。虽然问题是同步的。您是否也看过我在您回答后创建的第二个编辑示例(不使用 flatMap)。
猜你喜欢
  • 2018-10-17
  • 2018-09-18
  • 2021-06-01
  • 2017-05-02
  • 2017-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多