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();
私も2セントを入れると思った。私はこのパターンを使用します:
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();
}
}
Disposable でdisposeメソッドを探していると思います。
subscribeメソッドはDisposableを返します( link )
私はそれをドキュメントでより明確に見つけることはできないようですが、これは機能します( jsbin ):
var observable = Rx.Observable.interval(100);
var subscription = observable.subscribe(function(value) {
console.log(value);
});
setTimeout(function() {
subscription.dispose();
}, 1000)
不思議なことに、登録解除はあなたのために働いているようですが、それは私のために働いていません...
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();
}
}
ngOnDestroy(){
mySubscription.unsubscribe();
}
コンポーネントを破壊する間、rxjs unsubscribeのサブスクライブ解除を優先します。つまり、不必要なメモリリークを回避するためにDOMから削除します。
個人的には、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();
}
}
推奨されるアプローチは、takeUntil演算子などのRxJS演算子を使用することです。以下は、使用方法を示すコードスニペットです。
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
つかいます
if(mySubscription){
mySubscription.unsubscribe();
}