Observable(ストリーム)のOperatorでよく使われるものにmap
とmergeMap
があります。
メソッド名は似ていますが役割は異なります。今回はmap
とmergeMap
の違いについて紹介します。
RxJSに関する基礎知識がある前提で話を進めます。RxJSの基本情報の詳細解説は【RxJS入門】Observable、Observer、subscribe、Operatorの概要・関係性で紹介しています。
mapについて
map
はObservableから受け取ったメッセージの値を変換し、新たなメッセージを作成するOperatorです。
以下のコードでは『1 → 2 → 3』というストリームをmap
を利用して『1A → 2A → 3A』というストリームに変換しています。
import { of } from "rxjs";
import { map } from "rxjs/operators";
const observable = of(1, 2, 3); // 『1 → 2 → 3』というストリーム
observable
.pipe(
// 『1』というメッセージを受け取って『1A』というメッセージに変換
// 『2』というメッセージを受け取って『2A』というメッセージに変換
// 『3』というメッセージを受け取って『3A』というメッセージに変換
map(message => `${message}A`)
)
// mapによって作成された新たなストリーム『1A → 2A → 3A』のメッセージを取得
.subscribe(message => console.log(message));
実行結果
1A
2A
3A
mergeMapについて
mergeMapは以下の処理を行うOperatorです。
- Observableから受け取ったメッセージをもとに新たなObservableを作成
- メッセージごとに作成された複数のObservableを合成し、新たな1つのObservableを作成
以下のコードでは『1 → 2 → 3』というストリームをmergeMap
を利用して『1A → 1B → 1C → 2A → 2B → 2C → 3A → 3B → 3C』というストリームに変換しています。
const observable = of(1,2,3); // 『1 → 2 → 3』というストリーム
observable
.pipe(
// mergeMap内で作成された複数のストリーム(『1A → 1B → 1C』, 『2A → 2B → 2C』, 『3A → 3B → 3C』)を合成して新たなストリームを作成
mergeMap(message =>
// 『1』というメッセージを受け取って『1A → 1B → 1C』というストリームを作成
// 『2』というメッセージを受け取って『2A → 2B → 2C』というストリームを作成
// 『3』というメッセージを受け取って『3A → 3B → 3C』というストリームを作成
of(`${message}A`, `${message}B`, `${message}C`)
)
// mergeMapによって作成された新たなストリーム『1A → 1B → 1C → 2A → 2B → 2C → 3A → 3B → 3C』のメッセージを取得
.subscribe(message => console.log(message));
実行結果
1A
1B
1C
2A
2B
2C
3A
3B
3C
mapとmergeMapの違い
map
はメッセージを新しいメッセージに変換します。一方mergeMap
はメッセージからObservableを作成します。
そしてmergeMap
にはmap
と違い、『複数のObservableの合成』というプロセスがあります。
mapとmergeMapの使い分け
メッセージを変換したり、メッセージを引数としたメソッドを実行したりする場合はmap
を利用します。
一方、pipe
(Operatorを呼び出すためのメソッド)の中でfrom
やof
といったObservableを作成するメソッドを利用する場合はmergeMap
を利用します。
さいごに
map
とmergeMap
のような関係性を持つOperatorはほかに、switch
とswitchMap
、concat
とconcatMap
、exhaust
とexhaustMap
があります。
mergeMap
・switchMap
・concatMap
・exhaustMap
の違いは、作成された複数のObservableの合成方法です。
mergeMap
・switchMap
・concatMap
・exhaustMap
の違いの詳細解説は【RxJS】concatMap, mergeMap, switchMap, exhaustMapの違いで紹介しています。
Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!