みなさんこんにちは、現役エンジニアのサメハックです
未経験からWebエンジニアに転職し、
正社員として5年働いたのちフリーランスとして独立しました。
Angularの解説シリーズです。
今回はunsubscribeの重要性について学んでいきましょう!
駆け出しエンジニアや未経験の方、
また新入社員を指導する先輩社員にとっても
わかりやすいように解説していきます!
- unsubscribeの重要性がわかる
※PCにnpm、nodeがインストールされている前提で記述します。
yarn等をお使いの方は読み替えてください。
subscribeとは
subscribeとは、Observableを購読・実行するための関数です。
例えばserviceファイルで保管したdata$というObservableを購読した場合は
以下のような処理になると思います。
this.service.data$.subscribe(
(受け取った値) => {
// data$が更新されると自動的にこの処理が呼ばれる
}
)
RxJSに慣れていないと、購読という概念が理解し辛いかと思いますが、
ここでいう購読とは、ウォッチャ/監視と読み替えていただくと理解しやすいと思います。

この場合、data$が更新されると自動的にsubscribe内の処理が実行されます。
また、今回のテーマからズレるので深く触れませんが
Observableはsubscribeすることで初めて動作します。
監視した値が更新されると自動で実行されるよ!
unsubscribeとは
unsubscribeとはsubscribeで設定した購読を停止する処理です。
Angularを触ったことがない人にとっては馴染みがないと思いますが、
subscribeで購読した設定は自動では解除されず、
特にSPAではページ遷移しようがコンポーネントが破棄されようが
ずーーーっと値を監視し、処理が実行されてしまいメモリリークの原因となります。

subscribeとunsubscribeは必ずセットで使う必要があります。
subscribeとunsubscribeは必ずセットで使うよ!
購読停止(unsubscribe)するための前提知識
前提知識として以下の2点を抑えておく必要があります。
・Observable.subscribe()はSubscriptionオブジェクトを返す
・Subscriptionオブジェクトはunsubscribe関数を持っており、
これを実行することでObservableの購読停止ができます
unsubscribeする構文1
const subscription = this.service.data$.subscribe(
(受け取った値) => {
// data$が更新されると自動的にこの処理が呼ばれる
}
)
// 購読の停止
subscribe.unsubscribe();
unsubscribeする構文2※オススメ
// 購読設定停止用
private subscriptions = new Subscription();
this.subscriptions.add(
this.service.data$.subscribe(
(受け取った値) => {
// data$が更新されると自動的にこの処理が呼ばれる
}
)
);
/**購読を停止 */
this.subscriptions.unsubscribe();
最も汎用性が高いので、基本的にこれを使おう!
購読を停止するタイミング
ngOnDestroy※コンポーネントが削除されたタイミング
購読を停止する最もポピュラーなタイミングはngOnDestroyです。
// 購読設定停止用
private subscriptions = new Subscription();
ngOnInit() {
this.subscriptions.add(
this.service.data$.subscribe(
(受け取った値) => {
// data$が更新されると自動的にこの処理が呼ばれる
}
)
);
}
ngOnDestroy() {
/**コンポーネントが破棄されたタイミングで購読を停止 */
this.subscriptions.unsubscribe();
}
ngOnDestroyというのはAngularのライフサイクルで、
コンポーネントが破棄されたタイミングで実行されます。
購読の停止ができるよ!
関数内※重要
関数内で購読設定をすることはあまりないですが、
NGRXを使ったシステムではSTOREに保管したデータを
関数内で取得したいケースが出てきます。
myFunc() {
/* 処理1 */
this.store.select(selectData).subscribe(
(受け取った値) => {
// selectDataの対象が更新されると自動的にこの処理が呼ばれる
}
);
/* 処理2 */
}
このような関数が存在した場合、一度myFunc()を実行すると
this.store.select(selectData).subscribe( /*略*/ );
上記の処理は関数が終了しても生き続けてしまい、
selectDataの対象が更新されると突然subscribe()の処理だけが実行されてしまいます。
このように意図しない動作が起こりうるので、関数内でsubscribeを実行する場合には
ngOnDestroyに頼らず、関数終了時にunsubscribeを実行することが大切です。
myFunc() {
// 購読設定停止用
const myFuncSubscriptions = new Subscription();
/* 処理1 */
myFuncSubscriptions.add(
this.store.select(selectData).subscribe(
(受け取った値) => {
// selectDataの対象が更新されると自動的にこの処理が呼ばれる
}
);
)
/* 処理2 */
// 購読の停止
myFuncSubscriptions.unsubscribe()
}
まとめ

- subscribe・・・Observableを購読(=監視)するための関数、購読対象が更新されると呼ばれる
- unsubscribe・・・subscribeで設定した購読を停止する処理
- subscribeとunsubscribeは必ずセットで使う
- unsubscribeするタイミング①コンポーネントが破棄されるタイミング
- unsubscribeするタイミング②subscribeを含む関数の終了時

満足いただけたら、1クリックなのでSNSフォローしてもらえると嬉しいです🦈