避免在循环中使用嵌套的可观察订阅的正确方法是啥?
Posted
技术标签:
【中文标题】避免在循环中使用嵌套的可观察订阅的正确方法是啥?【英文标题】:What is the correct way to avoid using a nested observable subscription in a loop?避免在循环中使用嵌套的可观察订阅的正确方法是什么? 【发布时间】:2017-05-04 05:54:39 【问题描述】:我通过 Angularfire2 使用 Angular2 和 Firebase 从 Firebase 实时数据库(基本上是一个大型 JSON 对象)获取一些数据。
我有一个投票系统。民意调查位于“民意调查”节点中,民意调查响应位于“民意调查”节点中。要将这些链接在一起,我使用了“投票响应链接”节点。
所以基本上,要获得投票响应,我必须获取所有链接,然后从链接中获取响应。
下面的代码有效,但我觉得这是一种糟糕的做法。这么一说,我也不知道怎么做才对。
this.teamPollsService.getPollLinkList(id).subscribe((linkList) =>
this.responses = [];
for (let link of linkList)
this.teamPollsService.getResponse(link['$key']).subscribe((response) =>
this.responses.push(response);
);
);
我希望有人能阐明执行此操作的正确方法及其背后的原因?
任何帮助将不胜感激。
谢谢。
【问题讨论】:
【参考方案1】:如果您想以 RxJS 方式执行此操作,则可以使用 concatAll()
解压缩列表,然后使用 concatMap()
将每个项目转换为您想要的任何项目 this.teamPollsService
。
this.teamPollsService.getPollLinkList(id)
.concatAll()
.concatMap(link => this.teamPollsService.getResponse(link['$key']))
.subscribe(team => console.log(team));
(我没有测试这段代码)
运算符concatAll()
展平数组(请参阅RxJS: JSON data with an array, processing each item further in the stream 或Merge subarrays using Observables)。然后concatMap()
从内部 Observable 重新发出一个值。
您也可以使用mergeMap()
,它不会等到前一个 Observable 完成(不保证相同的项目顺序)。
【讨论】:
嗨,马丁。感谢您的回答。这部分对我有用。问题是即使存在 2 个或更多,它也只返回 1 个“响应”。 一个响应在哪里? 在最后的订阅console.log中。一项民意调查可以有多个响应,这意味着有多个链接 如果getPollLinkList()
发出多个数组,则没有区别。只需确保getPollLinkList()
在第一次发射后没有发送完整的信号。
所以也许我在这里感到困惑,但是当我调用 getPollLinkList().concatAll().concatMap(link => console.log(link)) return...
时,它只记录 1/4 个对象(第一个)。这是正确的吗?以上是关于避免在循环中使用嵌套的可观察订阅的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章