我已閱讀了大量關於Angular的Observable
s的退訂帖子,並且他們都提到僅在組件/指令中需要這樣做。取消訂閱非Component/Directive類中的Observable
所以我的問題是:
我們需要從Observable
S IN非組件/指令類如退訂在服務或基本上包含訂閱Observable
s的任何其他類?
我已閱讀了大量關於Angular的Observable
s的退訂帖子,並且他們都提到僅在組件/指令中需要這樣做。取消訂閱非Component/Directive類中的Observable
所以我的問題是:
我們需要從Observable
S IN非組件/指令類如退訂在服務或基本上包含訂閱Observable
s的任何其他類?
您取消訂閱組件,因爲當您從DOM中刪除它們(例如,使用*ngIf
或其他)時,RxJS鏈將持有對您在那裏創建的觀察者的引用。因此引入內存泄漏。
一般而言,您不必在服務中取消訂閱,因爲它們在應用程序的整個生命週期中都存在。
但是,在Angular中,您可以創建一個組件,例如僅向其後代提供不同的服務實例(這意味着您可能在應用程序中具有相同服務類的多個實例)。在這種情況下,您應該手動取消訂閱(可能在銷燬定義它們的組件時)。
我認爲重要的是要解釋爲什麼取消訂閱是重要的。沒有必要從流中取消訂閱,但性能可能有優勢,在某些情況下,取消訂閱作爲功能的一部分非常重要。
說取消訂閱是消費者的責任也很重要。流「強制」消費者退訂的唯一方法是完成或錯誤。
在Angular服務中,如果您最終訂閱了一個流,取消訂閱是很好的做法,除非您有充分的理由繼續傾聽。下面是一個(人爲的)例子:
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable()
export class MyService {
constructor(private session: Session) { }
isLoggedIn(): Observable<boolean> {
return Observable.create(observer => {
const innerSubscription = this.session.subscribe(session => {
if (session.user.isLoggedIn) {
observer.next(true);
}
observer.next(false);
});
return function unsubscribe() {
innerSubscription.unsubscribe(); // this "cleans up" our subscription.
};
});
}
}
還有其他更好的方法來編寫這段代碼,它只是一個例子。所以在這種情況下,我們有一個訂閱會話的非Component/Directive。每次會話發生變化時,我們都會查看用戶是否已登錄,並通知我們的聽衆是否已登錄。如果每個人都退訂我們,我們仍然會收聽this.session
,除非我們(服務)明確退訂。
簡而言之,我們可以設定一個規則:每當訂閱應該比**無限**'Observable'短時,我們必須在任何**情況下取消訂閱。組件/指令中的訂閱只是最常見的情況。這是真的嗎? –
@AlexanderAbakumov是的,這基本上是我遵循的規則。 – martin