Ответ 1
Вы хотите отказаться от подписки?
mySubscription.unsubscribe();
Как отменить подписку в Angular2? Кажется, что у RxJS есть метод dispose, но я не могу понять, как получить к нему доступ. Поэтому у меня есть код, который имеет доступ к EventEmitter и подписывается на него, например:
var mySubscription = someEventEmitter.subscribe(
(val) => {
console.log('Received:', val);
},
(err) => {
console.log('Received error:', err);
},
() => {
console.log('Completed');
}
);
Как я могу использовать mySubscription
для отмены подписки?
Вы хотите отказаться от подписки?
mySubscription.unsubscribe();
Я думал, что тоже поставил свои два цента. Я использую этот шаблон:
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();
});
}
}
ИЗМЕНИТЬ
Я прочитал документацию на днях и нашел более рекомендуемый шаблон:
Плюсы:
Он управляет новыми подписками внутри и добавляет некоторые аккуратные проверки. Предпочитаете этот метод в функции:).
Минусы:
На 100% не понятно, что такое поток кода и как влияет подписка. Также не ясно (просто смотря на код), как он работает с закрытыми подписками, и если все подписки закрываются, если вызывается unsubscribe.
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();
}
}
Я бы подумал, что вы ищете метод dispose на Disposable.
метод subscribe возвращает ссылку Disposable ()
Я не могу найти его более явно в документах, но это работает (jsbin):
var observable = Rx.Observable.interval(100);
var subscription = observable.subscribe(function(value) {
console.log(value);
});
setTimeout(function() {
subscription.dispose();
}, 1000)
Как ни странно, отмена подписки работает для вас, пока она не работает для меня...
Слишком много разных объяснений отказа от подписки на Observables для ng2, потребовалось много времени, чтобы найти правильный ответ. Ниже приведен рабочий пример (я пытался сжать mousemove).
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();
}
}
ngOnDestroy(){
mySubscription.unsubscribe();
}
Предпочитают отказаться от подписки на rxjs при отмене подписки при уничтожении компонента, то есть удаление из DOM для предотвращения ненужных утечек памяти.
Я предпочитаю лично использовать Субъект, чтобы закрыть все подписки, которые компонент мог бы иметь на этапе разрушения жизненного цикла, который может быть достигнут следующим образом:
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();
}
}
Использование
if(mySubscription){
mySubscription.unsubscribe();
}
Рекомендуемый подход заключается в использовании операторов RxJS, таких как оператор takeUntil. Ниже приведен фрагмент кода, показывающий, как его использовать: -
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();
}
}
Вы можете найти подробное объяснение темы здесь