[英]Subscription runs in ngOnInit function after Component is destroyed and Revisited
對於 Angular 組件和 rxjs 訂閱,我遇到了一個非常奇怪的情況。
我有以下ngOnInit
和ngOnDestroy
函數
ngOnInit() {
zip(this.service.getMessage, this.service.getType)
.pipe(takeUntil(this.componentDestroyed$))
.subscribe(data => {
const notification = new Notification(data[0], data[1]);
this.notifications.push(notification);
});
}
ngOnDestroy(): void {
this.componentDestroyed$.next(true);
this.componentDestroyed$.complete();
}
在服務文件中使用 Source 和 Subject 范例設置值后,訂閱處於活動狀態,如下所示:
private messageSource = new BehaviorSubject<string>('');
private message = this.messageSource.asObservable();
private typeSource = new BehaviorSubject<number>(-1);
private type = this.typeSource.asObservable();
...
...
set setMessage(message: string) {
this.messageSource.next(message);
}
set setType(type: number) {
this.typeSource.next(type);
}
正如預期的那樣,初始訂閱工作正常。 但是,離開組件並導航回同一個組件會在ngOnInit
中再次運行zip
訂閱,即使在離開時組件被破壞后也是如此。 如何防止這種情況發生? 我也嘗試過定義訂閱變量並調用unsubscribe
。 我難住了。
為了擴展我的評論,RxJS BehaviorSubject
保存推送給它的當前值並在訂閱時立即發出它。 它還允許您在BehaviorSubject
上使用唯一的getValue()
function(或value
getter),從而允許您同步檢索它持有的當前值。 雖然這個 getter 的使用通常是不受歡迎的。
因此,在您的情況下,當您路由回組件時,訂閱會發出兩個可觀察對象先前持有的值。 相反,您可以使用Subject
不保存值並且僅在將值推送到它之后才發出的主題。
private messageSource = new Subject<string>();
private message = this.messageSource.asObservable();
private typeSource = new Subject<number>();
private type = this.typeSource.asObservable();
...
我還建議您查看 RxJS ReplaySubject
。 這是一個更靈活的多播可觀察對象。 它接收要緩沖的通知數量,並在新訂閱時立即發出它們。
因此, ReplaySubject(1)
(緩沖區 1)類似於BehaviorSubject
,只是它不需要默認值。 因此,如果您在尚未向其中推送任何內容時訂閱它,則它不會發出。
它對當前問題沒有幫助,但在您希望擁有 BehaviorSubject 的BehaviorSubject
但不希望處理不必要的默認值的情況下可能會有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.