如何处理未定义的 Observable
Posted
技术标签:
【中文标题】如何处理未定义的 Observable【英文标题】:How to handle undefined Observables 【发布时间】:2021-06-03 03:25:48 【问题描述】:在我的 Angular 服务中,我提供了一个名为 usageDoc$
的公共 Observable。
service.ts:
usageDoc$: Observable<IUsage>;
initializeUsageDoc()
//gets called in app.component.ts on app load
...
//some async db querying
this.usageDoc$ = this.firestore.getUsageDoc(user.uid); //getUsageDoc(..) returns Observable<IUsage>
组件.ts
localDoc: any;
ngOnInit()
this.service.usageDoc$.subscribe(doc=>this.localDoc=doc);
这会导致以下错误:cannot read property subscribe of undefined...
as usageDoc$
is not yet set on the component init.目前我正在使用一种解决方法,即在服务中创建第二个可观察的usageDocReady$ = new Subject<boolean>
,一旦设置usageDoc$
,就会发出。
有没有更好的方法来解决这个问题?我可以用默认值以某种方式初始化 usageDoc$
吗?
我知道如果我使用异步管道在模板中订阅我不会有这个问题,但我需要一个普通变量来显示问题,因此使用localDoc
。
【问题讨论】:
【参考方案1】:我建议使用带有缓冲区 1 的 ReplaySubject
。它可以确保未来的订阅者获得最后一次发射,同时避免任何 undefined
错误。
private usageDocSrc = new ReplaySubject<IUsage>(1);
public usageDoc$ = this.usageDocSrc.asObservable();
initializeUsageDoc()
//gets called in app.component.ts on app load
...
//some async db querying
this.firestore.getUsageDoc(user.uid).subscribe(
next: value => this.usageDocSrc.next(value)
);
如果您不想使用ReplaySubject
,那么我不明白需要Observable
。您可以直接从 getUsageDoc()
函数返回 observable。
initializeUsageDoc(): Observable<IUsage>
//gets called in app.component.ts on app load
...
//some async db querying
return this.firestore.getUsageDoc(user.uid);
尽管这会为每次订阅initializeUsageDoc()
调用getUsageDoc()
之前的所有语句。
【讨论】:
拥有usageDoc$
和usageDocSrc
有什么意义?
@BojanKogoj:这是一种习惯力量,使用来自 Subject
或 ReplaySubject
等多播的 asObservable()
构造。有些人宁愿不使用它:usageDoc$ = new ReplaySubject<IUsage>(1)
。另请参阅here。
如果您试图阻止任何人从外部服务中获取下一步,那么这是有道理的。在这种情况下,也将 usageDocSrc
设为私有?
@BojanKogoj:是的,这是惯例(或者至少以前是这样)。我已经更新了答案。以上是关于如何处理未定义的 Observable的主要内容,如果未能解决你的问题,请参考以下文章