如何在Angular2中取消订阅
如何取消Angular2中的订阅? RxJS似乎有一个处置方法,但我不知道如何访问它。 所以我有代码可以访问一个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(); }); } }
编辑
我有一天看了文档,发现了一个更推荐的模式:
ReactiveX / RxJS /认购
优点:
它在内部pipe理新的订阅并添加一些整齐的检查。 会喜欢这个方法的function:)。
缺点:
代码stream是什么以及订阅如何受到影响并不是100%。 也不清楚(只是从代码中看)如何处理封闭订阅,以及如果所有订阅都在调用取消订阅时closures。
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(); } }
编辑:这不适用于RxJS 5,这是angular2正在使用。
我原以为你正在寻找一次性的处置方法。
订阅方法返回一个Disposable( 链接 )
我似乎无法在文档中更明确地find它,但是这起作用( jsbin ):
var observable = Rx.Observable.interval(100); var subscription = observable.subscribe(function(value) { console.log(value); }); setTimeout(function() { subscription.dispose(); }, 1000)
奇怪的是,取消订阅似乎是为你工作,而它不适合我…
对于取消订阅ng2的许多不同的解释,花了很多时间find正确的答案。 下面是一个工作的例子(我试图节制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中删除,以避免不必要的内存泄漏
使用
if(mySubscription){ mySubscription.unsubscribe(); }
我个人更喜欢使用Subject来closures组件在销毁生命周期中可能具有的所有订阅,这可以通过以下方式实现:
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(); } }