2017-09-26 79 views

回答

0

您取消訂閱組件,因爲當您從DOM中刪除它們(例如,使用*ngIf或其他)時,RxJS鏈將持有對您在那裏創建的觀察者的引用。因此引入內存泄漏。

一般而言,您不必在服務中取消訂閱,因爲它們在應用程序的整個生命週期中都存在。

但是,在Angular中,您可以創建一個組件,例如僅向其後代提供不同的服務實例(這意味着您可能在應用程序中具有相同服務類的多個實例)。在這種情況下,您應該手動取消訂閱(可能在銷燬定義它們的組件時)。

+0

簡而言之,我們可以設定一個規則:每當訂閱應該比**無限**'Observable'短時,我們必須在任何**情況下取消訂閱。組件/指令中的訂閱只是最常見的情況。這是真的嗎? –

+0

@AlexanderAbakumov是的,這基本上是我遵循的規則。 – martin

1

我認爲重要的是要解釋爲什麼取消訂閱是重要的。沒有必要從流中取消訂閱,但性能可能有優勢,在某些情況下,取消訂閱作爲功能的一部分非常重要。

說取消訂閱是消費者的責任也很重要。流「強制」消費者退訂的唯一方法是完成或錯誤。

在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,除非我們(服務)明確退訂。