Angular 2 多个(相似的)观察值的组合

Angular 2 combining of multiple (similar) observables

我找到了很多详细说明如何将多个可观察调用组合成一个可观察调用的示例,但根据我的发现,这些调用总是假定至少以下一项:

1:调用次数已知 2:调用次数固定 3:调用是将不同的对象合而为一。 (如 arg1 => call1,arg2 => call2)

但是我没有找到任何关于如何处理 Observables 的组合的适当信息,当这些调用是动态进行时,或者当您不希望将结果映射到不同的变量,而是希望扩展您正在访问的列表时正在收集。

给出一个可以应用的用例:一个用户可以注册多个 "groups" 产品。每个组都与一个 ID 相关联,该 ID 用于从远程服务获取产品。组是从所有组中取出所有产品,将它们连接在一起,并显示给用户。

对我来说最合乎逻辑的解决方案似乎是等到所有调用完成,同时将结果收集到另一个列表中,从那里很容易将这些列表编译成一个单一的、想要的结果,但我我们一直无法找到有效实现这一目标的方法 - 并且很想知道其他人是否有关于如何最好地解决这个问题的想法。

let responses = Array<Observable<Articles>>
    for (let id of subscriptions) {
        let response = this.http.get(producturl + id, headers).map(
            //insert mapping...
        );
    responses.push(response);
}

从这里开始,我尝试使用 .merge() 尝试将 "responses" 合并在一起,但感觉我对命令不够熟悉/滥用它。我也试过遍历 Observables 并依次订阅它们,但这似乎既不是最佳的,也没有产生想要的结果。我已经尝试了更多,但在我看来,这两个选项最有可能走上正确解决方案的正确轨道......如果需要更多代码来查看潜在问题可能出在哪里,我会很乐意分享 -并感谢您的任何意见。

您可以将 forkJoin 与普通的 reduce 一起使用:

let responses: Array<Observable<Articles>> = [];
for (let id of subscriptions) {
    let response: Observable<Articles> = this.http.get(producturl + id, headers).map();
    responses.push(response);
}

Observable.forkJoin(responses)
   .map(response => response.reduce((a,b) => {return a.concat(b)}))
   .subscribe((response: Articles[]) => {
       console.log(response);
      //output is a flat array of all Articles
});

不要忘记添加 rxjs 运算符:

import 'rxjs/add/observable/forkJoin';