Angluar2如何优化:Observable调用多个Observable?

时间:2016-07-11 05:30:21

标签: angular observable

要求:在远程服务器上调用observable以获取产品ID列表。致电Firebase以获取产品详细信息(针对每个产品ID)。

以下代码有效但感觉更像是一个promise实现,而不是一个可观察的实现。请注意,代码示例是简化的,有些是伪代码。

理论上,这可以通过调用一个返回所有产品的Firebase observable来解决,例如:产品在(35,68)。但我无法在Firebase中找到解决方法。相反,我为每个产品ID打了一个电话。

this.predicitionioService.getProductIds()
    .subscribe(
            ids => {
                this.productService.getProduct(ids[0].id).subscribe(product => this.product1 = product);
                this.productService.getProduct(ids[1].id).subscribe(product => this.product2 = product);
            }
    );

flatMap是这里所需要的。但返回的数据仅适用于最后一个产品。

this.predicitionioService.getProductIds()
.flatMap((ids) => this.productService.getProduct(ids[0].id))
.flatMap((ids) => this.productService.getProduct(ids[1].id))
.subscribe(
合并种类让我在那里但也在订阅下一个函数中返回产品ID。我需要产品有一个索引,例如产品1,2,3。我不能只绑定一个列表。这似乎适用于分配我自己的索引,例如我++。但这再次变得混乱。

this.predicitionioService.getProductIds()
.merge(
    this.productService.getProduct(ids[1].id),
    this.productService.getProduct(ids[2].id)
)
.subscribe(

有没有更好的方法用可观察的方法实现它?

2 个答案:

答案 0 :(得分:3)

var maxConcurrent = 5;

this.predicitionioService.getProductIds() // => Observable of array of ids, 1 item 
  .mergeMap(ids => Observable.from(ids))   // => Observable of ids
  .mergeMap(id => this.productService.getProduct(id.id), null, maxConcurrent) // => Observable of products
  .subscribe(product => { /* do stuff */ }); // do stuff to each product

注意:   

  • 从RxJS 5开始,flatMap是mergeMap的别名。   
  • 如果您确实需要将产品作为数组获取,请在.subscribe前添加.toArray()   
  • maxConcurrent参数是getProduct的最大并发请求数。如果您需要保留产品的顺序(与原始ids数组中的顺序相同),请将其设置为1 - 但速度会更慢。 (mergeMap = 1 maxConcurrent等同于concatMap

  • 答案 1 :(得分:1)

    这应该做你需要的:

    this.predicitionioService.getProductIds()
        .flatMap((ids) => {
            return Observable.forkJoin(
                ids.map(
                    (id) => this.productService.getProduct(id.id)
                )
            );
        })
        .subscribe((products) => {
            //do stuff
        });
    

    这将返回一个包含getProduct();

    所有结果的数组