¿Cómo se cancela una suscripción en Angular2? RxJS parece tener un método de eliminación, pero no puedo averiguar cómo acceder a él. Así que tengo un código que tiene acceso a un EventEmitter y se suscribe a él, como este:
var mySubscription = someEventEmitter.subscribe(
(val) => {
console.log('Received:', val);
},
(err) => {
console.log('Received error:', err);
},
() => {
console.log('Completed');
}
);
¿Cómo puedo usar mySubscription
para cancelar la suscripción?
javascript
angular
rxjs
Michael Oryl
fuente
fuente
Respuestas:
¿Quiere darse de baja?
fuente
mySubscription
TypeScript. Quiero evitar escribirmySubscription: any
en mi clase.import { Subscription } from "rxjs";
y para darse de bajaif (!mySubscription.closed) { mySubscription.unsubscribe(); }
.import { Subscription } from 'rxjs/Subscription';
ayudará a mantener el tamaño de su paquete bajoPensé que también había puesto mis dos centavos. Yo uso este patrón:
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(); }); } }
EDITAR
Leí la documentación el otro día y encontré un patrón más recomendado:
ReactiveX / RxJS / Suscripción
Pros:
Administra las nuevas suscripciones internamente y agrega algunas comprobaciones ordenadas. Preferiría este método en la función :).
Contras:
No está 100% claro cuál es el flujo de código y cómo se ven afectadas las suscripciones. Tampoco está claro (solo mirando el código) cómo se manejan las suscripciones cerradas y si todas las suscripciones se cierran si se llama a cancelar suscripción.
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(); } }
fuente
takeWhile
operador. Enfoque descrito aquí: brianflove.com/2016/12/11/anguar-2-unsubscribe-observablesEDITAR: Esto no se aplica a RxJS 5, que es lo que usa angular2.
Pensé que estaba buscando el método de eliminación en Desechables .
Parece que no puedo encontrarlo más explícitamente en los documentos, pero esto funciona ( jsbin ):
var observable = Rx.Observable.interval(100); var subscription = observable.subscribe(function(value) { console.log(value); }); setTimeout(function() { subscription.dispose(); }, 1000)
Extrañamente, la cancelación de la suscripción parece funcionar para ti, mientras que a mí no me funciona ...
fuente
Demasiadas explicaciones diferentes sobre la cancelación de suscripción en Observables para ng2, me llevó años encontrar la respuesta correcta. A continuación se muestra un ejemplo de trabajo (estaba tratando de acelerar el movimiento del mouse).
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(); } }
fuente
ngOnDestroy(){ mySubscription.unsubscribe(); }
Prefiere darse de baja de rxjs unsubscribe's mientras destruye el componente, es decir, elimina del DOM para evitar pérdidas de memoria innecesarias
fuente
Personalmente, prefiero usar un sujeto para cerrar todas las suscripciones que un componente pueda tener en el paso del ciclo de vida de destrucción, lo que se puede lograr de esta manera:
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(); } }
fuente
El enfoque recomendado es utilizar operadores RxJS como el operador takeUntil . A continuación se muestra el fragmento de código que muestra cómo usarlo: -
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(); } }
Puede encontrar una explicación detallada del tema aquí.
fuente
Utilizar
if(mySubscription){ mySubscription.unsubscribe(); }
fuente
if (!mySubscription.closed) { mySubscription.unsubscribe(); }
import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { SomeAPIService } from '../some_file/someAPIService.service.ts @Component({ templateUrl: './your_Page.html', styleUrls: ['./your_Styles.scss'] }) export class (your class) implements OnInit, OnDestroy { // This is a subject variable at it simplest form private unsubscribe$ = new Subject<void>(); constructor (private someAPIService : SomeAPIService) {} ngOnit(): void { this.someAPIService.getTODOlist({id:1}) .pipe(takeUntil(this.unsubscribe$)) .subscribe((value: SomeVariable) => { // What ever value you need is SomeVariable },) } ngOnDestroy(): void { // clears all, page subscriptions this.unsubscribe$.next(); this.unsubscribe$.complete(); } `}
fuente