【RxJS】combineLatestオペレータとは?「使い方」や「プログラム例」などを解説!

この記事ではRxJSの『combineLatestオペレータ』について、

  • combineLatestオペレータとは
  • combineLatestオペレータの「使い方」と「プログラム例」

などを分かりやすく説明するように心掛けています。ご参考になれば幸いです。

RxJSのcombineLatestとは

RxJSのcombineLatestは、複数のObservableを入力として取り、それぞれのObservableの最新の値を組み合わせて新しいObservableを出力するオペレータです。

以下にcombineLatestを用いたプログラム例を示しています。

import { combineLatest, timer } from 'rxjs';

// 1秒後に0を出力し、その後4秒ごとに「1→2→3→4→・・・」というデータを流すObservable
const timerOne$ = timer(1000, 4000);

// 2秒後に0を出力し、その後4秒ごとに「1→2→3→4→・・・」というデータを流すObservable
const timerTwo$ = timer(2000, 4000);

// combineLatestを使用して、2つのObservableの最新の値を組み合わせて新しいObservableを出力する
const combined$ = combineLatest([timerOne$, timerTwo$]);

combined$.subscribe((value) => console.log(value));

// ログ
// [ 0, 0 ]
// [ 1, 0 ]
// [ 1, 1 ]
// [ 2, 1 ]
// [ 2, 2 ]
// [ 3, 2 ]

上記のプログラムでは、combineLatestを使用して、2つのObservable(timerOne$timerTwo$)の最新の値を組み合わせて新しいObservableを出力しています。

あわせて読みたい

timerオペレータ』については下記の記事で詳しく説明しています。興味のある方は下記のリンクからぜひチェックをしてみてください。

combineLatestの返り値は配列のObservableなので、以下のプログラムに示すように、配列の分割代入を使用することもできます。

import { combineLatest, timer } from 'rxjs';

// 1秒後に0を出力し、その後4秒ごとに「1→2→3→4→・・・」というデータを流すObservable
const timerOne$ = timer(1000, 4000);

// 2秒後に0を出力し、その後4秒ごとに「1→2→3→4→・・・」というデータを流すObservable
const timerTwo$ = timer(2000, 4000);

// combineLatestを使用して、2つのObservableの最新の値を組み合わせて新しいObservableを出力する
const combined$ = combineLatest([timerOne$, timerTwo$]);

// 配列の分割代入を使用
combined$.subscribe(([timerValueOne, timerValueTwo]) => {
  console.log(`Timer One:${timerValueOne}  Timer Two:${timerValueTwo}`);
});

// ログ
// Timer One:0  Timer Two:0
// Timer One:1  Timer Two:0
// Timer One:1  Timer Two:1
// Timer One:2  Timer Two:1
// Timer One:2  Timer Two:2
// Timer One:3  Timer Two:2

また、以下に示すように、combineLatestは関数を用いて、Observableの形を変更することもできます。

import { combineLatest, timer } from 'rxjs';

// 1秒後に0を出力し、その後4秒ごとに「1→2→3→4→・・・」というデータを流すObservable
const timerOne$ = timer(1000, 4000);

// 2秒後に0を出力し、その後4秒ごとに「1→2→3→4→・・・」というデータを流すObservable
const timerTwo$ = timer(2000, 4000);

// combineLatestを使用して、2つのObservableの最新の値を組み合わせて新しいObservableを出力する
// 関数を用いて、組み合わせたObservableの形を変更することもできる
const combined$ = combineLatest([timerOne$, timerTwo$], (timerValueOne, timerValueTwo) => {
    let timeradd = timerValueOne + timerValueTwo;
    return `Timer One(${timerValueOne}) + Timer Two(${timerValueTwo}) = ${timeradd}`;
  }
);

combined$.subscribe((value) => console.log(value));

// ログ
// Timer One(0) + Timer Two(0) = 0
// Timer One(1) + Timer Two(0) = 1
// Timer One(1) + Timer Two(1) = 2
// Timer One(2) + Timer Two(1) = 3
// Timer One(2) + Timer Two(2) = 4
// Timer One(3) + Timer Two(2) = 5

combineLatestの注意点

combineLatestは組み合わせる全てのObservableが最初のデータを発行した後に新しいデータを出力します。したがって、非常に長い時間を要するObservableがある場合、そのObservableが初めて値を発行するまで結果は得られません。

以下のプログラムを見てみましょう。

import { combineLatest, timer } from 'rxjs';

// 1秒後に0を出力し、その後4秒ごとに「1→2→3→4→・・・」というデータを流すObservable
const timerOne$ = timer(1000, 4000);

// 10後に0を出力し、その後4秒ごとに「1→2→3→4→・・・」というデータを流すObservable
const timerTwo$ = timer(10000, 4000);

// combineLatestを使用して、2つのObservableの最新の値を組み合わせて新しいObservableを出力する
const combined$ = combineLatest([timerOne$, timerTwo$]);

combined$.subscribe((value) => console.log(value));

// ログ
// [ 2, 0 ]
// [ 3, 0 ]
// [ 3, 1 ]
// [ 4, 1 ]
// [ 4, 2 ]

combineLatestは、全てのObservableから少なくとも一度はデータが発行されるまで、何も出力しません、このプログラムでは、10秒後に最初の値を発行するObservable(timerTwo$)があります。したがって、10秒後までcombineLatestにより作成される新しいObservable(combined$)が最初のデータを発行しません。

なお、最初のデータを発行する時点では、timerOne$は既に3つの値(0と1と2)を発行していて、4つ目の値(3)を発行するところです。一方、timerTwo$は最初の値(0)を発行したばかりです。したがって、combined$が最初に発行する配列は[2, 0]になります。その後、それぞれのObservable(timerOne$timerTwo$)が新しい値を発行するたびに、その最新の値が組み合わせられて、出力されます。

本記事のまとめ

この記事ではRxJSの『combineLatestオペレータ』について、以下の内容を説明しました。

  • combineLatestオペレータとは
  • combineLatestオペレータの「使い方」と「プログラム例」

お読み頂きありがとうございました。