我有一个相当常见的用例。我从FirebaseDatabase加载对象数组,并从Firebase存储中附加图像。combineLatest不订阅参数Observables,不提供数据
FirebaseDatabase基于查询返回Observable。每次数据库中的数据都会改变,Observable会发出更新后的查询结果。我还从存储API通过映射附加承诺到结果的每个条目的[域,ImagePromise]元组的每个条目
getDomainObj(){
return this.af.database.list(this.listRef)
.map((mps: Domain[]) =>
mps.map((mp: Domain) =>
[mp, this.getImage(mp['$key'])]));
}
两个问题:
- 一些议员没有一个图像。
- 由于图像不在图像中,因此图像变化时,可观察图像不会发出。为了解决这个问题,我添加了一个Cloud函数来发送每个图像更新的推送通知(这个问题的范围之外,它的工作原理,所以不需要进入)。每个MP是自己的PubSub的话题,我们在客户端订阅主题,以及
我通过映射
解决这些问题都得到可观察到的,将发出每次图像特定MP更新的上传this.mpSvc.getDomainObj()
.map((tupleArray: [Domain, Promise<string>][]) =>
tupleArray.map(([mp, imageSrcPromise]: [Domain, Promise<string>]) => {
return [mp,
Observable.fromPromise(imageSrcPromise) // get initial image
.startWith(null) // make sure that it emits at least once
.concat(// updates
this.mpSvc.signUpForPictureUpdates(mp['$key'])
.map(([id, imageSrc]: [string, string]) => imageSrc))
];
})
)
mpSvc.signUpForPictureUpdates
返回一个可观察DOMAINID-imageSrc元组,将发射每个域的图像将得到重新上传
现在最终目标是具有可观察到的[域,imageSrc]阵列的时间的,每次都会发出Domai中任何一个图像n对象更改或任何Domain对象更改,或者查询结果发生更改。
首先我再次重新映射,而不是发射[域,可观察]对的阵列,发射可观察<的阵列[域,imageSrc]>
.map((tupleArray: [Domain, Observable<string>][]) =>
tupleArray.map(([mp, imageSrcObservable]: [Domain, Observable<string>]) =>
imageSrcObservable.map((imageSrc: string) => [mp, imageSrc])))
我现在有一个可观察的阵列的对的可观察性。每当一个域或查询结果将发生变化时,父级Observable就会发出,并且每当特定域的映像发生更改时,子级都会发出。
对于最后一步,我将observable的子项组合到一个observable中,并将switchMap组合到它中。
.switchMap((imageObservables: Observable<[Domain, string]>[]) =>
Observable.combineLatest(imageObservables)
)
结果正确subsribed来(事实上,它显示在通过ngFor角模板|异步,但是这也是范围之内)。
不幸的是,结果不是预期的结果。实际上,我有四个来自查询的结果对象,两个有图像,两个没有。我所看到的并不一致 - 有时两种图像都加载,有时是一种,最常见的是两种。
具体来说,如果我是一个记录行添加到末尾,像这样:
.do(x => console.log('final', x), x => console.error('finalerror', x),() => console.log('finalcomplete'));
我总是至少有一个日志符合在imageSrc空,但几乎没有过额外的线条与解决实际imageSrcs 。
订阅的最后一步(combineLatest)获取所有数据之前正确
我在做什么错?
编辑:寻找到这个更长时间后,这个问题肯定是用combineLatest
。我试着用imageObservables[1].map(x=>[x])
更换combineLatest
和它完美的作品(尽管当然只返回一个值,而不是数组的。此外,通过combineLatest步进使我有些收盘这是奇怪的,因为需要在任何时候被关闭呢?