冷热 AngularFire 可观察对象

Hot and cold AngularFire observables

我的 Angular2/Firebase 应用程序的组件中有以下代码:

ngOnInit() {
  this.allItems = this.angularFireDatabase.object(`projects/${id}/results`).map(
    results => { 
      const x = itemMapper(results); 
      console.log(x); // <-- executes three times
      return x; 
  });

  const groupedData = this.allItems.map(groupMapper);
  this.towers = groupedData.map(towerMapper);
  this.units = groupedData.map(unitMapper);
}

我在带有 async 管道的模板中使用 this.allItemsthis.towersthis.units

<sanddance [items]="allItems | async">

<p-dataTable [value]="towers | async">
<p-dataTable [value]="units | async">

代码运行正常,但是问题是日志执行了3次--也就是说,创建this.allitems的映射是[=38= 】 三遍。如果我删除 this.towersthis.units 分配,那么日志将按预期只执行一次。换句话说,this.towers = groupedData.map(towerMapper); 行似乎导致对创建 this.allItems 的映射器进行额外调用,尽管它不需要而且我也不想这样做。它甚至可以重新访问 Firebase 数据库中的数据,这显然是个问题,尤其是因为这是大量数据?

基于我对 "hot" 和 "cold" observable 的有限理解,AngularFire observable 似乎被视为 "hot",并在下游有人尝试映射时重新触发它(或订阅它,本质上就是 async 管道所做的)。

我错过了什么?

AngularFire2 可观察对象是冷可观察对象。每个订阅都将看到一个单独的 Firebase Reference 在内部创建 - 然后将侦听器附加到该 Firebase

当您的代码段中的组合可观察对象被订阅时,每个对象都会影响对 AngularFire2 object 可观察对象的订阅。如果您想改用单个订阅,可以使用 share 运算符:

import 'rxjs/add/operator/share';

this.allItems = this.angularFireDatabase.object(`projects/${id}/results`).map(
  results => { 
    const x = itemMapper(results); 
    console.log(x); // <-- this should execute only once
    return x; 
}).share();

const groupedData = this.allItems.map(groupMapper);
this.towers = groupedData.map(towerMapper);
this.units = groupedData.map(unitMapper);

share运算符:

Returns a new Observable that multicasts (shares) the original Observable. As long as there is at least one Subscriber this Observable will be subscribed and emitting data. When all subscribers have unsubscribed it will unsubscribe from the source Observable. Because the Observable is multicasting it makes the stream hot. This is an alias for .publish().refCount().