オペレータとは
- オペレーターは、 リアクティブプログラミング で、Observableクラスで扱う ストリームの高度な操作 を可能にするための関数です。
- リアクティブプログラミング:流れてくるデータ(ストリーム)に関連性と操作を宣言的に記述する手法のことです
- Observable:ストリームを扱うクラスです
- 例:マウス操作やHTTPリクエストでデータ取得するなど
- ストリームは川の様なイメージです
- つまりオペレータは、川(ストリーム)の 中間で処理する仕組み であり、流れてきたデータを下流でキャッチして、オブジェクト間のデータのやり取りをします
主要なオペレータの使い方
ofオペレータ
- 渡ってきたデータに何もせずそのまま流します
import { of } from 'rxjs';
const cats = of('cat1', 'cat2','cat3');
cats.subscribe(cat => console.log(cat)); // cat1, cat2, cat3
Mapオペレータ
- 渡ってきたデータを受け取って違うデータを返します
import { of } from 'rxjs';
import { map } from 'rxjs/operators';
const nums = of(1, 2, 3)
.pipe(
map(num => num * num)
).subscribe(
num => console.log(num) // 1, 4, 9
);
filterオペレータ
- 流れてきたデータチェックを行い、条件にあった場合のみ、ストリームが流れます
- 文字列一致判定、typeOf演算子で、どの種類の演算子か判定するなどに使えます
import { of } from 'rxjs';
import { filter } from 'rxjs/operators';
const cats = of('mike', 'tama', 'mikeneko')
.pipe(
filter(cat => cat === 'mike')
).subscribe(
cat => console.log( `matched: ${cat}`) //matched: mike
);
debounceTimeオペレータ
- 連続してデータを流すときに、指定時間遅延後、最後のデータを一度のみストリームを流します
-
debounceTime(250)
では、250msec以下のストリームは流れない
-
- 何回も流れないように制御できます
import { of } from 'rxjs';
import { map, debounceTime } from 'rxjs/operators';
// 連続する最後の処理から250ミリ秒遅延後、最後のデータを1度だけストリームに流す
const nums = of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.pipe(
debounceTime(250),
map(value => `debounceTime(250): ${value}`)
)
.subscribe(
value => console.log(value) // debounceTime(250): 10
);
throttleTimeオペレータ
- 連続してデータを流すときに、中間処理を250ミリ秒間隔で間引くことができます
- windowのスクロールを間引きたいときなどに使います
import { of } from 'rxjs';
import { map, throttleTime } from 'rxjs/operators';
// 連続する処理を250ミリ秒間隔で間引く
const nums = of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.pipe(
throttleTime(250),
map(value => `throttleTime(250): ${value}`)
)
.subscribe(
value => console.log(value) // debounceTime(250): 1
);
distinctUntilChangedオペレータ
- 前回とデータが違う時のみデータを流します
- 同じデータを連続で流したくない時に使います
import { of } from 'rxjs';
import { distinctUntilChanged, map } from 'rxjs/operators';
// 前回と値が違う場合のみ、ストリームを流す
const cats = of('mike', 'mike', 'mike' ,'mikeneko')
.pipe(
distinctUntilChanged(),
).subscribe(
cat => console.log( `distinctUntilChanged: ${cat}` )
);
// distinctUntilChanged: mike
// distinctUntilChanged: mikeneko
switchMapオペレータ
- Stream Aに流れてくるデータを元に、別のStream Bを流します
-
Observable
を切り替えて、別のObservable
を返すことができます - 別のStream Bが終わる前に、元のStream A が流れた場合、途中までのStream Bはキャンセルされて、始めから再び実行されます
- HTTPクライアントでリクエストを投げた後、処理を途中で止める時に使います
import { interval, of } from 'rxjs';
import { map, switchMap, take} from 'rxjs/operators';
const cats = of('mike', 'mike', 'mike' ,'mikeneko') // StreamA
.pipe(
switchMap(cat => {
return interval(1000).pipe( // StreamB
take(3),
map((index) => `switchMap: ${index} => ${cat}`)
);
})
)
.subscribe(
cat => console.log( `${cat}` )
);
skipオペレータ
- 指定した回数分、意図的にデータを流さない時に使います
import { of } from 'rxjs';
import { skip } from 'rxjs/operators';
const cats = of('mike', 'mike', 'mike' ,'mikeneko')
.pipe(
skip(2),
)
.subscribe(
cat => console.log( `skip: ${cat}` )
);
//skip: mike
//skip: mikeneko
takeオペレータ
- 指定回数のみ実行するときに使います
- 初めの一回のみ実行したいなど
import { of } from 'rxjs';
import { take } from 'rxjs/operators';
let count = 0;
const cats = of('mike', 'tama', 'mike' ,'mikeneko', 'tama')
.pipe(
take(3)
)
.subscribe(
cat => console.log( `take(${++count}): ${cat}` )
);
//take(1): mike
//take(2): tama
//take(3): mike
finalizeオペレータ
- 引数で渡したコールバック関数を、ストリームが流れた最後に実行します
- ストリームが流れた最後に処理を行う時に使います
- HTTPリクエストで画面にローディングアイコンを表示した際に、処理の再後にアイコンを非表示にするなど
import { interval } from 'rxjs';
import { map, take, finalize } from 'rxjs/operators';
interval(1000) // 1sずつカウントアップ
.pipe(
map(index => `finalize(map): ${index + 1}`),
take(3),
finalize(() => {
setTimeout(() => console.log( 'finalize!(ˆoˆ)' ) , 100);
}),
)
.subscribe(
val => console.log( `${val}` )
);
// finalize(map): 1
// finalize(map): 2
// finalize(map): 3
// finalize!(ˆoˆ)
(参考サイト)
- 様々なオペレータの動作を視覚的に確認できます🌟
RxJS marbles