2016-11-29 4 views
1

In einem Reiseführer für Angular 2 heißt es:Entsorgung des Abonnements, wenn beobachtbare vervollständigt

„Das Standardverhalten von Observablenoperatoren ist das Abonnements zu entsorgen, sobald Das Gesamt() oder .error() -Nachrichten sind veröffentlicht. Denken Sie daran, dass RxJS entworfen wurde, um die meiste Zeit in einer "Feuer und Vergessen" Mode verwendet zu werden. "

In einer früheren Seite gibt es ein Beispiel für beobachtbare und Abonnement.

example here.

Sie können dort sehen, dass nach 3 Sekunden die onbservable ".complete()" s. Wenn Sie jedoch erneut auf die Schaltfläche Init() klicken und die Methode init() aufrufen, wird der Abonnent weiterhin informiert. Also, was meint der Autor mit "disposed the subscription"?

Code:

import {Component} from '@angular/core'; 
import {Observable} from 'rxjs/Observable'; 

@Component({ 
    selector: 'app', 
    template: ` 
     <b>Angular 2 Component Using Observables!</b> 

     <h6 style="margin-bottom: 0">VALUES:</h6> 
     <div *ngFor="let value of values">- {{ value }}</div> 

     <h6 style="margin-bottom: 0">ERRORs:</h6> 
     <div>Errors: {{anyErrors}}</div> 

     <h6 style="margin-bottom: 0">FINISHED:</h6> 
     <div>Finished: {{ finished }}</div> 

     <button style="margin-top: 2rem;" (click)="init()">Init</button> 
    ` 
}) 
export class MyApp { 

    private data: Observable<Array<number>>; 
    private values: Array<number> = []; 
    private anyErrors: boolean; 
    private finished: boolean; 

    constructor() { 
    } 

    init() { 
     this.data = new Observable(observer => { 
      setTimeout(() => { 
       observer.next(42); 
      }, 1000); 

      setTimeout(() => { 
       observer.next(43); 
      }, 2000); 

      setTimeout(() => { 
       observer.complete(); 
      }, 3000); 
     }); 

     let subscription = this.data.subscribe(
      value => this.values.push(value), 
      error => this.anyErrors = true, 
     () => this.finished = true 
    ); 
    } 

} 

Antwort

0

Dies liegt daran, jedes Mal, wenn Sie auf der init klicken Sie eine neue beobachtbaren erstellen. Versuchen Sie, Ihre Linie zu ändern:

this.data = ... 

zu

if(!this.data){ 
    this.data = ... 

und Sie werden feststellen, dass weitere Anrufungen von init sehen nicht den Handler aufrufen

0

die Erstellung Ihrer beobachtbare Bewegen innerhalb des Konstruktors.

Sie können ein Thema in Ihrem Konstruktor haben, z.

constructor() { 
    super(); 
    this.data$ = new Rx.Subject(); 
} 

dann in Ihrem Click-Handler können Sie so etwas wie:

this.data.onNext(42)

Wenn Sie die onComplete auslösen auch manuell müssen Sie prüfen, ob der Strom vor onNext

0
Aufruf abgeschlossen ist

Wenn Sie Subskriptionen für Dinge wie den Standort oder die Routerereignisse erstellen, behalten die Subskriptionen das vorhandene Ereignis bei, nachdem Ihre Komponente zerstört wurde, was zu pre führen kann Es ist schwierig, Fehler und unerwünschtes Verhalten zu finden.

Beim Absetzen von http-Rufe wird die Verbindung nach einer erfolgreichen Übertragung geschlossen und Ihr Abonnement wird geschlossen, weil die beobachtbaren Brände abgeschlossen sind(). Hier

ist ein Beispiel für einen Code, den ich in letzter Zeit geschrieben habe:

ngOnInit(): void { 
    ... 
    this.electionStateSubscription = this.electionState.getState() 
      .subscribe((state: ElectionState) => this.state = state); 
} 

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

In diesem Beispiel eine redux wie Statusspeicher aufgebaut haben und in dieser Komponente, um es am abonnieren möchte. Die electionState ist immer vorhanden und wird nie abgeschlossen.

Wenn diese Komponente zerstört wird, ist das Abonnement entsorgt. Sonst würde dies jedes Mal, wenn die Komponente initialisiert wird, ein neues Abonnement erstellen, was, wenn nichts anderes passiert, zu Leistungsproblemen führen kann.

Verwandte Themen