質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Angular

Angularは、JavaScriptフレームワークです。AngularJSの後継であり、TypeScriptベースで実装されています。機能ごとに実装を分けやすく、コードの見通しが良いコンポーネント指向です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

2647閲覧

Angularでライフサイクルメソッドを使用して無限に動くのを防ぐ

kenji267

総合スコア50

Angular

Angularは、JavaScriptフレームワークです。AngularJSの後継であり、TypeScriptベースで実装されています。機能ごとに実装を分けやすく、コードの見通しが良いコンポーネント指向です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2020/04/28 14:48

編集2020/04/29 01:05

前提・実現したいこと

Angular9で、
カウンターからobservable を作成したりするとします。
https://angular.io/guide/rx-library
以下のようなコンポーネントで作成した場合、テンプレートでログが出力され続けます。

import { Component } from '@angular/core'; import { interval } from 'rxjs'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'angular-tour-of-heros'; constructor( ){} ngOnInit(): void { // Create an Observable that will publish a value on an interval const secondsCounter = interval(1000); // Subscribe to begin publishing values secondsCounter.subscribe(n => console.log(`It's been ${n} seconds since subscribing!`)); } }

この処理をすると、このコンポーネントを利用するテンプレートでは、延々に処理が続き、メモリリークを起こすとも記載されるサイトも見られます。
https://angular.io/guide/lifecycle-hooks#ondestroy

これを回避するために、ngOnDestroy()を使用しようと考えいます。
https://angular.io/guide/lifecycle-hooks#lifecycle-sequence

質問

上記に対しどう対応するのかご教授ください。
マニュアルからでは、ngOnDestroy()をどうやって使用すればいいのかわかりません。
そもそもngOnDestroy()する意味を間違えているのであればご指摘ください。

参考

ここに問題に対して試したことを記載してください。
→説明を読んだだけでは利用の仕方が分からず。

補足情報(FW/ツールのバージョンなど)

https://qiita.com/ksh-fthr/items/ccd9861f919c4aa30ae8
https://lacolaco.hatenablog.com/entry/2018/04/10/230413

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

ngOnDestroyメソッドはコンポーネントが破棄されるときに呼ばれるライフサイクルメソッドです。
これを実行しただけではIntervalで指定している処理が止まるわけでなく、この中にIntervalを止める記述を書く必要があります。

そのための前提として以下を知っておく必要があります
・Observable.subscribe()メソッドは戻り値としてSubscriptionオブジェクトを返している。
・Subscriptionオブジェクトはunsubscribeメソッドを持っており、これを実行することでObservableの購読を停止することが出来る。

上記を踏まえて以下のように変更してみてください

export class AppComponent implements OnInit, OnDestroy { title = 'angular-tour-of-heros'; intervalSubs: Subscription; constructor( ){} ngOnInit(): void { // Create an Observable that will publish a value on an interval const secondsCounter = interval(1000); // Subscribe to begin publishing values this.intervalSubs = secondsCounter.subscribe(n => console.log(`It's been ${n} seconds since subscribing!`) ); } ngOnDestroy(): void{ if (this.intervalSubs){ this.intervalSubs.unsubscribe(); } } }

投稿2020/04/30 00:21

keisukeh

総合スコア657

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kenji267

2020/04/30 10:11

引き続き回答ありがとうございます! また前提知識のフォローありがとうございます。 後、購読が停止されているかの確認ですが、手段はありますでしょうか? こういう仕様であるというのが回答になるのでしょうか? 再度の質問になりますが回答頂ければ助かります。
keisukeh

2020/04/30 12:59

購読時に実行している関数が実行されていなかったら停止していることになります。 今回の場合だと関数内のconsole.logが出力されていなければ大丈夫です
kenji267

2020/04/30 13:58

最後に確認させてください。もう止めるようにします。 `実行されていなかったら停止`とのことですが、ある程度の時間(どこかで設定している?)が経つと、 メモリがある上限以上とかの判断をして止まると認識していいでしょうか?、そこあたりもう少し 具体的に頂けたら思います。 しつこくてすみません・・・
keisukeh

2020/04/30 14:30 編集

提示したサンプルコードの中で説明すると ngOnDestroyが実行されたタイミングで this.intervalSubs.unsubscribe(); を実行していますので その処理で購読が解除されて、以降は console.log('It's been ${n} seconds since subscribing!') は実行されなくなります ngOnDestroyの実行されるタイミングはコンポーネントが削除されたときです(ルーティングなどでこのコンポーネントが表示されなくなった時)
keisukeh

2020/04/30 14:37

ただし、AppComponentは変更を加えてなければすべてのコンポーネントの上位にくるルートコンポーネントになっているはずなのでページを閉じない限りはずっと削除されません。 任意のタイミングやユーザーの操作によって購読を解除したい場合はクリック処理などの実行のタイミングで this.intervalSubs.unsubscribe(); を実行すれば大丈夫です
kenji267

2020/04/30 14:39

そういうことか、投げ出さず質問に回答頂きたいありがとうございました!
guest

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問