以下是模仿我的代碼的基本 observables:
class DataService {
#data = this.http.get<Data[]>('https://example.com/getData').pipe(
timeout(15000),
catchError(err => of([]))
)
#adaptedData = this.#data.pipe(
map(data => data.map(obj => new AdaptedObj(obj)))
)
#pollAdapted = timer(0, 60000).pipe(
switchMap(() => this.#adaptedData),
shareReplay(1)
)
get get() { return this.#adaptedData }
get poll() { return this.#pollAdapted }
}
然后在我的代碼的其他地方,我有一個額外的可觀察層,可以進一步操縱資料以用于一組特定的組件。例子:
class DataAnalyzerService {
constructor(private dataService: DataService){}
#analyzedDataStore = new BehaviorSubject<AnalyzedData[]>([])
get analyzedData() { return this.#analyzedDataStore.value }
#analyzedData = this.dataService.poll.pipe(
filter(objs => objs.length > 0),
map(objs => objs.map(obj => new AnalyzedObj(obj))),
tap(analyzedData => this.#analyzedDataStore.next(analyzedData))
)
#metricCalculator = () => {
const data = this.analyzedData
// Do calculations and filtration
return dashboardMetricsArr
}
#dashboardStats = this.#analyzedData.pipe(
switchMap(() => of(this.#metricCalculator))
)
get dashboardStats() { return this.#dashboardStats }
}
然后在我的組件中,我使用帶有異步管道的儀表板指標,如下所示:
<ng-container *ngIf="(dashboardStats | async) as stats">
// Use the Data
<ng-container>
我之所以將 observables 分解成這樣,是因為有不同的組件需要不同分析層的資料,此外,有些組件只需要一次資料,而另一些則需要以 1 分鐘的間隔不斷更新。
Currently, the application works fine, but when I logout or exit the components that use the data, I notice the http requests are ongoing each minute because the DataService poll observable is never unsubscribed. Right now, I only have a single subscription initialized using the async pipe in the template, so I know I am closing that specific subscription when I navigate away from that component or log out all-together. Additionally, I have verified that both the #analyzedData and #dashboardStats observables cease execution after navigating away. Only the poll observable continues.
Any ideas on how to get the polling to stop until I am back in a component that needs it?
uj5u.com熱心網友回復:
shareReplay具有手冊refCount中描述的配置選項:
從 RXJS 版本 6.4.0 開始,添加了一個新的多載簽名,以允許手動控制操作員內部參考計數器下降到零時發生的情況。如果 refCount 為真,一旦參考計數下降到零,源將被取消訂閱,即內部 ReplaySubject 將被取消訂閱。所有新訂閱者都將從新的 ReplaySubject 接收到值發射,這反過來將導致對源 observable 的新訂閱。另一方面,如果 refCount 為 false,則不會取消訂閱源,這意味著內部 ReplaySubject 仍將訂閱源(并可能永遠運行)。
您使用shareReplay(1),它使用默認值refCount: false,因此它不會取消訂閱。開啟自動退訂的參考計數:
shareReplay({bufferSize: 1, refCount: true})
uj5u.com熱心網友回復:
有幾個選項
使用以下庫
在組件中實體化應該用于檢查訂閱是否通過使用
takeUntil運算子取消訂閱的主題private destroy$ = new Subject<void>();this.data$.pipe(takeUntil(this.destroy$))ngOnDestroy(): void { this.destroy$.next(); this.destroy$.complete(); }
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/444505.html
標籤:angular typescript rxjs observable async-pipe
上一篇:使用MUI組件分頁無法按預期作業
下一篇:如何訪問介面打字稿中的屬性
