如何在 Angular2 中取消订阅
How to cancel a subscription in Angular2
如何在 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();
编辑: 这不适用于 angular2 使用的 RxJS 5。
我还以为你在 Disposable 上寻找 dispose 方法。
the subscribe method returns a Disposable (link)
我似乎无法在文档中更明确地找到它,但这有效 (jsbin):
var observable = Rx.Observable.interval(100);
var subscription = observable.subscribe(function(value) {
console.log(value);
});
setTimeout(function() {
subscription.dispose();
}, 1000)
奇怪的是,取消订阅似乎对你有效,而对我无效...
使用
if(mySubscription){
mySubscription.unsubscribe();
}
ngOnDestroy(){
mySubscription.unsubscribe();
}
最好在销毁组件时取消订阅 rxjs 取消订阅,即从 DOM 中删除以避免不必要的内存泄漏
取消订阅 ng2 的 Observables 有太多不同的解释,我花了很长时间才找到正确的答案。下面是一个工作示例(我试图限制 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();
}
}
我想我也投入了我的两分钱。我使用这种模式:
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% 清楚代码流是什么以及订阅是如何受到影响的。也不清楚(仅通过查看代码)它如何处理已关闭的订阅,以及如果调用取消订阅是否所有订阅都将关闭。
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();
}
}
我个人更喜欢使用 Subject 来关闭组件在销毁生命周期步骤中可能拥有的所有订阅,这可以通过这种方式实现:
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();
}
}
推荐的方法是使用 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();
}
}
你可以找到题目的详细解释here
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();
}
`}
如何在 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();
编辑: 这不适用于 angular2 使用的 RxJS 5。
我还以为你在 Disposable 上寻找 dispose 方法。
the subscribe method returns a Disposable (link)
我似乎无法在文档中更明确地找到它,但这有效 (jsbin):
var observable = Rx.Observable.interval(100);
var subscription = observable.subscribe(function(value) {
console.log(value);
});
setTimeout(function() {
subscription.dispose();
}, 1000)
奇怪的是,取消订阅似乎对你有效,而对我无效...
使用
if(mySubscription){
mySubscription.unsubscribe();
}
ngOnDestroy(){
mySubscription.unsubscribe();
}
最好在销毁组件时取消订阅 rxjs 取消订阅,即从 DOM 中删除以避免不必要的内存泄漏
取消订阅 ng2 的 Observables 有太多不同的解释,我花了很长时间才找到正确的答案。下面是一个工作示例(我试图限制 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();
}
}
我想我也投入了我的两分钱。我使用这种模式:
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% 清楚代码流是什么以及订阅是如何受到影响的。也不清楚(仅通过查看代码)它如何处理已关闭的订阅,以及如果调用取消订阅是否所有订阅都将关闭。
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();
}
}
我个人更喜欢使用 Subject 来关闭组件在销毁生命周期步骤中可能拥有的所有订阅,这可以通过这种方式实现:
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();
}
}
推荐的方法是使用 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();
}
}
你可以找到题目的详细解释here
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();
}
`}