2017-03-09 74 views
6

我知道,爲了防止內存泄漏,組件被銷燬時,我必須取消訂閱某些Observable(即:具有無限值值的Observable)值。我不需要這樣做有限的可觀測物,因爲他們會完成並自動地unsubscribeAngular 2/Rxjs:我真的需要退訂嗎?

但如果我創建一個無限Observable在我的組件(例如FormGroup.valueChanges,或QueryList.changes),這將是一個與包含它的成分破壞,所以我認爲,他們將沒有內存泄漏甚至如果我不要取消訂閱它。

下面是一個簡單的例子:

@Component({}) 
export class DummyComponent { 
    form: FormGroup; 

    constructor(private fb: FormBuilder) { 
     this.form = this.fb.group({ 
      firstName: [''], 
      lastName: [''] 
     }); 
     this.form.valueChanges.subscribe(
      x => console.log(x) 
     ); 
    } 
} 

在這裏,我不unsubscribethis.form.valueChanges做;當我的組件被銷燬時,this.form.valueChanges也將被銷燬。

這種情況下會不會有內存泄漏?

+3

您是否試圖添加一個完整的回調來訂閱(...)並檢查它是否在組件被銷燬時被調用? –

+0

我做了,並沒有被調用(我只用'this.form.valueChanges'做了測試)。 – freedonaab

+0

我想那樣更好但不必取消訂閱。我不會期望內存泄漏,因爲組件被銷燬時,它會被垃圾收集,並且你的訂閱。如果您訂閱或通過組件外部的訂閱(例如服務),那麼這可能會阻止組件被GCed,但是如果組件內的所有內容都不應該受到傷害。 –

回答

4

正如Babar提到的,您需要執行取消訂閱以阻止訂閱以繼續觀看更改。

對於您的特殊情況,我認爲您有一點。

當我在同一個組件中有很多訂閱時,我會做的一件事是以下內容。

首先我創建訂閱,訂閱類型爲空數組。

private subscriptions: Subscription[] = []; 

每當我需要做的認購時間我推入陣列

this.subscriptions.push(this.form.valueChanges.subscribe(x => console.log(x))); 

而在ngOnDestroy我退訂陣列內的每個訂閱。

ngOnDestroy(): void { 
    this.subscriptions.forEach((elem) => { elem.unsubscribe(); }) 
} 
+1

您可以使用subscription.add()方法爲彼此添加訂閱。那麼你只需要取消訂閱頂級訂閱。 – DarkNeuron

2

當你的組件被銷燬時,你的訂戶不是他們還在等待任何事件來到他們這將花費內存以及有時它可能會打擾你的邏輯。例如路由器事件訂閱,它會在您的應用中隨處觸發,並執行您在訂閱時執行的代碼。

我的第二種情況是,如果您在組件之間切換並且從未取消訂閱,您的應用將在一堆時間後掛斷,因爲每當您加載組件時,新訂閱者都會綁定。

@Component({}) 
export class DummyComponent implements OnDestroy { 
form: FormGroup; 
subscription: Subscription; // from rxjs 
constructor(private fb: FormBuilder) { 
    this.form = this.fb.group({ 
     firstName: [''], 
     lastName: [''] 
    }); 
    this.subscription = this.form.valueChanges.subscribe(
     x => console.log(x) 
    ); 
} 

ngOnDestroy(): void { 
    this.subscription.unsubscribe(); 
} 
}