20
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Unsubscribeしないこだれだ

Last updated at Posted at 2019-09-22

概要

Angular, RxJSを使う人であれば**「必ずunsubscribeする」**は何度も聞いたことがあると思います。以前書いた記事でも触れたように、この理由は「コンポーネントが破棄されてもSubscriptionだけが残り続けてしまうため」です。私も頭ではわかっていつつも実際にこれでハマった例をみたことがなかったのですが、ちょうど少し前にそういうケースに出くわしたのでデモを作ってみました。まだ使い始めでピンと来ない人などの理解の手助けになれば嬉しいです。

デモ

肝心のデモはこちらです。
簡単にシステムを説明します。左のボタンでどのおばけを出すか切り替えることができます。activeになったおばけは「おばけを出す」ボタンのクリックイベントをsubscribeするようになります。一度activeを切り替えるたびに、subscribeしていたコンポーネントのインスタンスは破棄されます。
このおばけのなかに、unsubscribeを忘れているおばけがいるのでデモを操作してどれか当ててみてください:ghost: 簡単なので書くまでもないかもしれませんが、次の解説欄に答えを載せます。

デモの解説

前述の通り、activeを切り替えるたびに、subscribeしていたコンポーネントのインスタンスは破棄されます。ですが、ngOnDestroyで正しくunsubscribeされていない場合はコンポーネントが破棄されてもsubscribeしているsubscriptionは破棄されません。そのため、別のおばけにactiveを切り替えても、「おばけを送る」ボタンを押した時に前のおばけも一緒に出てくるようになるのです。参考までに、今回のコードはこちらです。
それでは、デモの動きをまとめて答えを見てみましょう。

  • 1つめの:ghost:を選ぶ
  • 2つめの:ghost:を選ぶ
  • 「おばけを送る」
  • 1つめと2つめの:ghost:が出る
    :よって1つめのおばけはunsubscribeしわすれています。
  • 3つめの:ghost:を選ぶ
  • 「おばけを送る」
  • 1つめと2つめと3つめの:ghost:が出る
    :よって2つめのおばけはunsubscribeしわすれています。
  • 再度1つ目のおばけを選ぶ
  • 1つめのおばけx2、2つめのおばけが出ます
    :よって3つめのおばけはunsubscribeされています。

何が怖いのか

適当にactiveを切り替えてボタンを押すとわかると思いますが、後始末されてない場合、一度のイベント発火でのsubscribe処理がactiveを切り替えるたびにわさわさと増えていきます。 これがもし、おばけを出すのではなくバックエンドからデータを取得する処理だったらどうでしょうか。操作をするたびにどんどんリクエストが増え、画面が重くなっていきます。恐ろしいですね…:ghost:

おまけ:こういう時は後始末忘れかも

上記で述べたとおり、1つのイベントに対して1回しか走るはずのない処理(上記例で言えば、バックエンドへのリクエスト)がたくさん同時に起きている場合、後始末忘れが予測されます。
そのほかに、**「subscribe処理が思うような挙動をしない」**場合もこのケースがありえます。すでに述べたように、subscriptionは残っていてもコンポーネント自体は破棄されているので、例えばsubscribeの中でコンポーネントの変数を更新していても更新されないのです。console.logで確認して絶対にここにイベントは届いているのに、ビューに反映されない!ということがあれば、これも後始末忘れの可能性があります。

まとめ

特にエラーの出るような種類のものではないため、みんなで気をつけていくのが大事ですね:dog2:

20
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?