ホームページ  >  記事  >  ウェブフロントエンド  >  Angular での購読解除に関する簡単な説明

Angular での購読解除に関する簡単な説明

小云云
小云云オリジナル
2018-01-16 09:02:491535ブラウズ

この記事では主に、Angular でサブスクリプションをキャンセルするタイミングについての簡単な議論を紹介します。編集者はそれが非常に優れていると考えたので、参考として共有します。編集者をフォローして見てみましょう。皆さんのお役に立てれば幸いです。

Observable オブジェクトをサブスクライブするとき、またはイベント リスナーをセットアップするとき、ある時点でサブスクリプション解除操作を実行してオペレーティング システムのメモリを解放する必要があることはご存知かもしれません。そうしないと、アプリケーションでメモリ リークが発生する可能性があります。

ngOnDestroy ライフサイクル フックでサブスクリプション解除操作を手動で実行する必要がある一般的なシナリオをいくつか見てみましょう。

手動リリースリソースシナリオ

Form


export class TestComponent {

 ngOnInit() {
  this.form = new FormGroup({...});
  // 监听表单值的变化
  this.valueChanges = this.form.valueChanges.subscribe(console.log);
  // 监听表单状态的变化              
  this.statusChanges = this.form.statusChanges.subscribe(console.log);
 }

 ngOnDestroy() {
  this.valueChanges.unsubscribe();
  this.statusChanges.unsubscribe();
 }
}

上記の解決策は、他のフォームコントロールにも適用できます。

ルーティング


export class TestComponent {
 constructor(private route: ActivatedRoute, private router: Router) { }

 ngOnInit() {
  this.route.params.subscribe(console.log);
  this.route.queryParams.subscribe(console.log);
  this.route.fragment.subscribe(console.log);
  this.route.data.subscribe(console.log);
  this.route.url.subscribe(console.log);
  
  this.router.events.subscribe(console.log);
 }

 ngOnDestroy() {
  // 手动执行取消订阅的操作
 }
}

レンダラーサービス


export class TestComponent {
 constructor(
  private renderer: Renderer2, 
  private element : ElementRef) { }

 ngOnInit() {
  this.click = this.renderer
    .listen(this.element.nativeElement, "click", handler);
 }

 ngOnDestroy() {
  this.click.unsubscribe();
 }
}

無限のObservables

Interval() または fromEvent() 演算子を使用すると、無限の Observable オブジェクトが作成されます。この場合、それらを使用する必要がなくなったら、リソースを手動で購読解除して解放する必要があります。


export class TestComponent {
 constructor(private element : ElementRef) { }

 interval: Subscription;
 click: Subscription;

 ngOnInit() {
  this.interval = Observable.interval(1000).subscribe(console.log);
  this.click = Observable.fromEvent(this.element.nativeElement, 'click')
              .subscribe(console.log);
 }

 ngOnDestroy() {
  this.interval.unsubscribe();
  this.click.unsubscribe();
 }
}

Redux Store


export class TestComponent {

 constructor(private store: Store) { }

 todos: Subscription;

 ngOnInit() {
   /**
   * select(key : string) {
   *  return this.map(state => state[key]).distinctUntilChanged();
   * }
   */
   this.todos = this.store.select('todos').subscribe(console.log); 
 }

 ngOnDestroy() {
  this.todos.unsubscribe();
 }
}

リソースシナリオを手動で解放する必要はありません

AsyncPipe


@Component({
 selector: 'test',
 template: `<todos [todos]="todos$ | async"></todos>`
})
export class TestComponent {
 constructor(private store: Store) { }
 
 ngOnInit() {
   this.todos$ = this.store.select(&#39;todos&#39;);
 }
}

非同期パイプラインはサブスクリプション解除操作を自動的に実行し、その後メモリリークのリスクを回避します。

Angular AsyncPipe ソース コード スニペット


@Pipe({name: &#39;async&#39;, pure: false})
export class AsyncPipe implements OnDestroy, PipeTransform {
 // ...
 constructor(private _ref: ChangeDetectorRef) {}

 ngOnDestroy(): void {
  if (this._subscription) {
   this._dispose();
  }
 }
}

@HostListener


export class TestDirective {
 @HostListener(&#39;click&#39;)
 onClick() {
  ....
 }
}

@HostListener デコレータを使用する場合、イベント リスナーを追加するときに手動でサブスクライブを解除できないことに注意してください。イベント リスニングを手動で削除する必要がある場合は、次の方法を使用できます:


// subscribe
this.handler = this.renderer.listen(&#39;document&#39;, "click", event =>{...});

// unsubscribe
this.handler();

Finite Observable

HTTP サービスまたはタイマー Observable オブジェクトを使用する場合、手動でサブスクライブを解除する必要はありません。


export class TestComponent {
 constructor(private http: Http) { }

 ngOnInit() {
  // 表示1s后发出值,然后就结束了
  Observable.timer(1000).subscribe(console.log);
  this.http.get(&#39;http://api.com&#39;).subscribe(console.log);
 }
}

タイマーオペレーター

オペレーター署名

コードをコピー コードは次のとおりです:


public static timer(initialDelay:number | Date, period:number,scheduler:Scheduler):Observable

演算子関数

timer は、特定の時間間隔で無限の自動増加シーケンスを発行する Observable を返します。この間隔はユーザーが選択します。

演算子の例


// 每隔1秒发出自增的数字,3秒后开始发送
var numbers = Rx.Observable.timer(3000, 1000);
numbers.subscribe(x => console.log(x));

// 5秒后发出一个数字
var numbers = Rx.Observable.timer(5000);
numbers.subscribe(x => console.log(x));

最後のアドバイス

この記事「RxJS: Don't Unsubscribe」で、unsubscribe() メソッドの呼び出しをできるだけ少なくする必要があります。特異的な例は次のとおりです:

RREEE
TAKEUNTILオペレーターOPERATOR SIGNATURATURATURATURE


export class TestComponent {
 constructor(private store: Store) { }

 private componetDestroyed: Subject = new Subject();
 todos: Subscription;
 posts: Subscription;

 ngOnInit() {
   this.todos = this.store.select(&#39;todos&#39;)
           .takeUntil(this.componetDestroyed).subscribe(console.log); 
           
   this.posts = this.store.select(&#39;posts&#39;)
           .takeUntil(this.componetDestroyed).subscribe(console.log); 
 }

 ngOnDestroy() {
  this.componetDestroyed.next();
  this.componetDestroyed.unsubscribe();
 }
}

OPERATOR関数通知者が値を発するまで観察可能なソースが発した値をエミットします。


オペレーターの例


public takeUntil(notifier: Observable): Observable<T>

関連する推奨事項:


node.js パブリッシュ/サブスクライブ モードのメソッド


JavaScript パブリッシュ/サブスクライブ モードの使用方法の詳細な説明

PHP WeChat パブリック プラットフォーム開発サブスクリプションイベント処理_PHPチュートリアル

以上がAngular での購読解除に関する簡単な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。