Wie kündigt man ein Abonnement in Angular2? RxJS scheint eine Entsorgungsmethode zu haben, aber ich kann nicht herausfinden, wie ich darauf zugreifen soll. Ich habe also Code, der Zugriff auf einen EventEmitter hat und ihn wie folgt abonniert:
var mySubscription = someEventEmitter.subscribe(
(val) => {
console.log('Received:', val);
},
(err) => {
console.log('Received error:', err);
},
() => {
console.log('Completed');
}
);
Wie kann ich mySubscription
das Abonnement kündigen?
javascript
angular
rxjs
Michael Oryl
quelle
quelle
Antworten:
Möchten Sie sich abmelden?
quelle
mySubscription
TypeScript verwendet wird. Ich möchte vermeiden,mySubscription: any
in meiner Klasse zu schreiben .import { Subscription } from "rxjs";
und zur Abmeldungif (!mySubscription.closed) { mySubscription.unsubscribe(); }
.import { Subscription } from 'rxjs/Subscription';
wird helfen, Ihre Paketgröße niedrig zu haltenIch dachte, ich stecke auch meine zwei Cent ein. Ich benutze dieses Muster:
import { Component, OnInit, OnDestroy } from '@angular/core'; import { Subscription } from 'rxjs/Subscription'; @Component({ selector: 'my-component', templateUrl: 'my.component.html' }) export class MyComponent implements OnInit, OnDestroy { private subscriptions: Array<Subscription> = []; public ngOnInit(): void { this.subscriptions.push(this.someService.change.subscribe(() => { [...] })); this.subscriptions.push(this.someOtherService.select.subscribe(() => { [...] })); } public ngOnDestroy(): void { this.subscriptions.forEach((subscription: Subscription) => { subscription.unsubscribe(); }); } }
BEARBEITEN
Ich habe neulich die Dokumentation gelesen und ein empfohleneres Muster gefunden:
ReactiveX / RxJS / Abonnement
Vorteile:
Es verwaltet die neuen Abonnements intern und fügt einige ordentliche Überprüfungen hinzu. Würde diese Methode in der Funktion bevorzugen :).
Nachteile:
Es ist nicht 100% klar, wie der Codefluss aussieht und wie Abonnements betroffen sind. Es ist auch nicht klar (nur anhand des Codes), wie es mit geschlossenen Abonnements umgeht und ob alle Abonnements geschlossen werden, wenn das Abbestellen aufgerufen wird.
import { Component, OnInit, OnDestroy } from '@angular/core'; import { Subscription } from 'rxjs/Subscription'; @Component({ selector: 'my-component', templateUrl: 'my.component.html' }) export class MyComponent implements OnInit, OnDestroy { private subscription: Subscription = new Subscription(); public ngOnInit(): void { this.subscription.add(this.someService.change.subscribe(() => { [...] })); this.subscription.add(this.someOtherService.select.subscribe(() => { [...] })); } public ngOnDestroy(): void { /* * magic kicks in here: All subscriptions which were added * with "subscription.add" are canceled too! */ this.subscription.unsubscribe(); } }
quelle
takeWhile
Operators. Ansatz hier beschrieben: brianflove.com/2016/12/11/anguar-2-unsubscribe-observablesBEARBEITEN: Dies gilt nicht für RxJS 5, das von angle2 verwendet wird.
Ich hätte gedacht, Sie suchen nach der Entsorgungsmethode für Einwegartikel .
Ich kann es nicht expliziter in den Dokumenten finden, aber das funktioniert ( jsbin ):
var observable = Rx.Observable.interval(100); var subscription = observable.subscribe(function(value) { console.log(value); }); setTimeout(function() { subscription.dispose(); }, 1000)
Seltsamerweise scheint das Abbestellen für Sie zu funktionieren, während es für mich nicht funktioniert ...
quelle
Viel zu viele verschiedene Erklärungen zum Abbestellen von Observables für ng2 haben mich ewig gekostet, um die richtige Antwort zu finden. Unten ist ein funktionierendes Beispiel (ich habe versucht, die Mausbewegung zu drosseln).
import {Injectable, OnDestroy} from "@angular/core"; import {Subscription} from "rxjs"; @Injectable() export class MyClass implements OnDestroy { mouseSubscription: Subscription; //Set a variable for your subscription myFunct() { // I'm trying to throttle mousemove const eachSecond$ = Observable.timer(0, 1000); const mouseMove$ = Observable.fromEvent<MouseEvent>(document, 'mousemove'); const mouseMoveEachSecond$ = mouseMove$.sample(eachSecond$); this.mouseSubscription = mouseMoveEachSecond$.subscribe(() => this.doSomethingElse()); } doSomethingElse() { console.log("mouse moved"); } stopNow() { this.mouseSubscription.unsubscribe(); } ngOnDestroy() { this.mouseSubscription.unsubscribe(); } }
quelle
Ziehen Sie es vor, rxjs abzumelden, während Sie die Komponente zerstören, dh aus dem DOM entfernen, um unnötige Speicherlecks zu vermeiden
quelle
Ich persönlich bevorzuge es, einen Betreff zu verwenden, um alle Abonnements zu schließen, die eine Komponente im Schritt "Lebenszyklus zerstören" möglicherweise hat. Dies kann auf folgende Weise erreicht werden:
import { Component} from '@angular/core'; import { Subject } from "rxjs/Rx"; @Component({ selector: 'some-class-app', templateUrl: './someClass.component.html', providers: [] }) export class SomeClass { private ngUnsubscribe: Subject<void> = new Subject<void>(); //This subject will tell every subscriptions to stop when the component is destroyed. //********** constructor() {} ngOnInit() { this.http.post( "SomeUrl.com", {}, null ).map( response => { console.log( "Yay." ); }).takeUntil( this.ngUnsubscribe ).subscribe(); //This is where you tell the subscription to stop whenever the component will be destroyed. } ngOnDestroy() { //This is where we close any active subscription. this.ngUnsubscribe.next(); this.ngUnsubscribe.complete(); } }
quelle
Verwenden
if(mySubscription){ mySubscription.unsubscribe(); }
quelle
if (!mySubscription.closed) { mySubscription.unsubscribe(); }
Der empfohlene Ansatz besteht darin, RxJS-Operatoren wie den takeUntil- Operator zu verwenden. Unten sehen Sie das Code-Snippet, das zeigt, wie es verwendet wird: -
import { Component, OnInit, OnDestroy } from '@angular/core'; import { interval, Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; @Component({ selector: 'app-root', templateUrl: './app.component.html' }) export class AppComponent implements OnInit, OnDestroy { private ngUnsubscribe = new Subject(); constructor() { } ngOnInit() { var observable1 = interval(1000); var observable2 = interval(2000); observable1.pipe(takeUntil(this.ngUnsubscribe)).subscribe(x => console.log('observable1: ' + x)); observable2.pipe(takeUntil(this.ngUnsubscribe)).subscribe(x => console.log('observable2: ' + x)); } ngOnDestroy() { this.ngUnsubscribe.next(); this.ngUnsubscribe.complete(); } }
Eine ausführliche Erläuterung des Themas finden Sie hier
quelle