【问题标题】:Angluar2 How to Optimize: Observable Calls Multiple Observables?Angluar2 如何优化:Observable 调用多个 Observable?
【发布时间】:2016-11-12 23:23:05
【问题描述】:

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

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

理论上,这可以通过调用一个返回所有产品的 Firebase observable 来解决,例如其中 productid 在 (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(

merge 有点让我到达那里,但也会在 subscribe next 函数中返回产品 ID。我需要产品有一个索引,例如产品 1、2、3。我不能只绑定一个列表。这似乎适用于分配我自己的索引,例如我++。但这又变得一团糟。

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

有没有更好的方法用可观察的方法来实现这个?

【问题讨论】:

  • 只是为了澄清,您想获得一个 ID 列表以及您想要产品的每个 ID?结果应该是一个关联数组?

标签: angular observable


【解决方案1】:

这应该可以满足您的需要:

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

这将返回一个包含getProduct() 的所有结果的数组;

【讨论】:

    【解决方案2】:
    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 - 但它会更慢。 (mergeMapmaxConcurrent = 1 将等效于 concatMap
  • 【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-16
      • 2021-02-05
      • 1970-01-01
      • 1970-01-01
      • 2011-09-30
      • 2019-10-09
      • 2019-08-17
      • 1970-01-01
      相关资源
      最近更新 更多