问题描述
我发现在使用异步管道和在模板中手动订阅可观察对象之间存在区别,在讨论这些方法之间的区别的任何文章中我都没有看到。
比方说,我有一个带有可观察对象的组件,它侦听重载主题(@Input() reload = new ReplaySubject<void>(1)
),该组件会在路线更改时发出,以从服务器中获取其数据,而在本示例中,并没有这样做。永远不会被破坏-例如详细信息组件,其父级是所有详细信息组件的列表。
首先,使用subscribe()方法,如果获取请求出错,则可订阅的方法的观察对象也会出错,从而完成并停止发出值。这是预期的。如果我将路线更改为其他详细信息,则会发出重载主题,但是可观察到的组件已完成,因此它不执行任何逻辑:
@Input() public refresh: Observable<void>;
private refreshInternal = new ReplaySubject<GridViewParams>(1);
public refreshInternalObs = this.refreshInternal.asObservable();
private initializeInternalRefreshListener(): void {
this.refreshInternalObs
.pipe(
switchMap(() => this.httpRequest()),takeUntil(this.unsubscriber),finalize(() => {
// fires once after request error
// observable then completes
// and no logic ever fires again
})
)
.subscribe(() => {
// this code is never reached after obervable errors out once
});
}
private initializeExternalRefreshListener(): void {
this.refresh.pipe(takeUntil(this.unsubscriber)).subscribe(
() => {
// fires every time a notification is sent from parent,// even after refreshInterval is completed
this.refreshInternal.next();
},);
}
但是,当我改用异步管道方法时,在出现错误后切换路由会获取新值,就像异步管道在观察到错误后再次订阅一样。
<!-- gets new data every time even after refreshInternal erroring out -->
<ng-container *ngIf="this.refreshInternalObs | async as data">{{ data | json }}</ng-container>
...
@Input() public refresh: Observable<void>;
private refreshInternal = new ReplaySubject<GridViewParams>(1);
public refreshInternalObs = this.refreshInternal.asObservable();
private initializeInternalRefreshListener(): void {
// seems to not get completed after erroring out
this.refreshInternalObs
.pipe(
switchMap(() => this.httpRequest()),)
}
private initializeExternalRefreshListener(): void {
this.refresh.pipe(takeUntil(this.unsubscriber)).subscribe(
() => {
// fires every time a notification is sent from parent,this.refreshInternal.next();
},);
}
异步管道是如何做到的?是否是因为changeDetection(使用默认值)在每个周期都重新订阅了异步管道?还是异步管道使用某种“重试”逻辑?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)