2017-07-26 4 views
6

Von meinem Verständnis von Angular und RxJs gibt es zwei Möglichkeiten, Observables zu beenden. Sie können von ihnen oder takeUntil() und complete() verwenden. Im Folgenden finden Sie Beispiele für jeden Ansatz (im Pseudocode).Angular - was ist der bevorzugte Weg, um Observables zu beenden?

Der Abmelde() Ansatz

private _id: number; 
private _subscriptions: Subscription[] = []; 

constructor(private _route: ActivatedRoute) { 
    this._getId(); 
} 

public ngOnDestroy(): void { 
    this._subscriptions.forEach(
     subscription => subscription.unsubscribe() 
    ); 
} 

private _getId(): void { 
    this._subscriptions.push(
     this._route.params.subscribe(params => this._id = +params['id']) 
    ); 
} 

Die takeUntil() und vollständig (Ansatz)

private _id: number; 
private _ngUnsubscribe: Subject<void> = new Subject<void>(); 

constructor(private _route: ActivatedRoute) { 
    this._getId(); 
} 

public ngOnDestroy(): void { 
    this._ngUnsubscribe.next(); 
    this._ngUnsubscribe.complete(); 
} 

private _getId(): void { 
    this._route.params.takeUntil(this._ngUnsubscribe).subscribe(
     params => this._id = +params['id'] 
    ); 
} 

In Angular, ist es eine bevorzugte Art und Weise Observable zu beenden?

+2

Die bevorzugte Art und Weise in 'ngOnDestroy' ist, was Sie tun. Die einzige Sache, die ich hinzufügen könnte, ist zu überprüfen, dass die Werte "truthy" sind, dh nicht null oder nicht undefiniert, sonst erhalten Sie einen Fehler beim Versuch, 'unsubscribe()' aufzurufen. – Lansana

+1

Und beachten Sie, dass Sie häufige Observablen, wie die Router-Parameter in Ihrem Beispiel, oft nicht beenden müssen. Angular beendet sie automatisch. Siehe die Hinweise unten in diesem Dokumentabschnitt: https://angular.io/guide/router#activedroute-the-one-stop-shop-for-route-information – DeborahK

+1

siehe [diese Antwort] (https://stackoverflow.com/a/41177163/2545680) –

Antwort

4

Beide Ansätze sind korrekt, obwohl sie nicht gleichwertig sind.

Meiner Meinung nach (und Erfahrung) mit unsubscribe() machen in der Regel mehr Sinn und ist offensichtlicher für andere Entwickler, die keine umfangreiche Erfahrung mit RxJS haben.

Die Verwendung von takeUntil() wird vom Hauptentwickler von RxJS 5 (https://medium.com/@benlesh/rxjs-dont-unsubscribe-6753ed4fda87) empfohlen und ist manchmal einfacher zu handhaben als die Behandlung mehrerer Subskriptionsobjekte. Wenn Sie beispielsweise den Operator partition() verwenden, um einen Stream in zwei zu teilen, ist es einfacher, nur takeUntil(...).partition(...) zu verwenden.

Allerdings gibt es zwei wichtige Dinge:

  1. Diese beiden sind nicht die gleichen. Wenn Sie takeUntil() verwenden, vervollständigen Sie die Observable-Kette, was bedeutet, dass alle vollständigen Griffe aufgerufen werden, gefolgt von Abreißfunktionen. Auf der anderen Seite, wenn Sie aufrufen, werden nur Abreißfunktionen aufgerufen (einschließlich Operatoren wie finally()).

    Deshalb ist es sinnvoller, unsubscribe() zu verwenden. Mit takeUntil() haben Sie möglicherweise einen complete -Handler, der aufgerufen wird, obwohl Sie nur abbestellen wollten (ohne zu erwähnen, dass dies Operatoren auslöst, die mit dem -Signal wie repeat() arbeiten, das sich möglicherweise erneut anmeldet). Die Tatsache, dass Sie sich abmelden möchten, bedeutet nicht, dass die Quelle Observable abgeschlossen wurde. Sie interessieren sich nicht mehr für seine Werte, also ist es wahrscheinlich besser, in diesem Fall unsubscribe() zu verwenden.

    In der Praxis spielt es jedoch meist keine Rolle, ob Sie die Kette vervollständigen oder sich einfach abmelden.

  2. Sie können Subscription s zu einem einzigen zusammenstellen und sie alle auf einmal abmelden:

    const subscription = new Subscription(); 
    
    const sub1 = Observable...subscribe(...); 
    const sub2 = Observable...subscribe(...); 
    const sub3 = Observable...subscribe(...); 
    
    subscription.add(sub1).add(sub2).add(sub3); 
    
    ... 
    
    subscription.unsubscribe(); // unsubscribes all of them 
    
0

Die Art, wie ich das tue, ist, indem Sie zuerst auf ngOnDestroy überprüfen, wenn das Observable existiert. Wenn ja, dann abmelden. Im Folgenden finden Sie das Code-Snippet aus meiner App.

accountSubscriptionObj : Subscription; 

ngOnDestroy() { 
    if (this.accountSubscriptionObj) { 
     this.accountSubscriptionObj.unsubscribe(); 
    } 
    } 

Inzwischen brauchen Sie nicht von Async Rohr auszutragen, @HostListener, Finite beobachtbar sind. Wenn die Komponente zerstört wird, wird die asynchrone Leitung automatisch abgemeldet, um mögliche Speicherlecks zu vermeiden. Wenn Sie eine endliche Sequenz haben, müssen Sie sich normalerweise nicht abmelden, z. B. wenn Sie den HTTP-Dienst oder den Timer beobachten. Für mehr Referenz read here.

Verwandte Themen