6.2.0Subjectは、Observableであり、なおかつObserverです。Observableと違って、複数のObserverに値をマルチキャストできます。機能が加えられたサブクラスもいくつかあります。5公式「Manual」の「Subject」を下じきに、バージョン6に改め、コード例や解説も書き替えました。SubjectでマルチキャストするRxJSのSubjectはObservableを継承するサブクラスで、複数のObserverに値がマルチキャストできます。親のObservableは単一キャストで、実行したObserverが単独でオブジェクトを保持するのと異なる点です。Subjectは、Observerをイベントリスナーのように複数登録して扱います。SubjectはObservableです。Subjectを実行(サブスクライブ)してObserverが与えられると、Observableの場合と同じように値が送られます。Observerからは、実行されたのが単一キャストのObservableなのかマルチキャストのSubjectなのかはわかりません。Subjectのサブスクリプトは、内部的には実行して値を送るわけではありません。Observerを実行のリストに加えるだけです。イベントリスナーに似た仕組みといえます。SubjectはObserverでもあります。next()とerror()およびcomplete()の3つのメソッドを備えたオブジェクトです。next()に値を渡して呼び出せば、Subjectのリストに登録されたObserverすべてに値はマルチキャストで送られます。つぎのコードは、Observable.subscribe()メソッドでSubjectにふたつのObserverを加えたうえで、next()により値を送ります。2SubjectはObserverです。したがって、SubjectをObservable.subscribe()メソッドの引数にして呼び出すこともできます。すると、単一キャストのObservableをマルチキャストにすることができるのです。つぎのコードは、ObservableにSubjectを渡して実行することにより、登録された複数のObserverに値を送ります。02」04-01「Observableをつくる」参照)。3Subjectを継承するサブクラスには、あとに述べるBehaviorSubjectやReplaySubject、あるいはAsyncSubjectなどがあります。ObservableをマルチキャストにするObservableそのものは単一キャストで、ひとつのObserverにしか値を送れません。Subjectを介すれば、複数の通知先をもつマルチキャストのObservableにできます。Subjectにより、内部的に複数のObserverに同じObservableの実行を扱わせることができるのです。multicast()オペレータを使えば、複数のObserverをSubjectに登録し、Observableから受け取ったデータが送れます。前掲のコードは、multicast()オペレータを使って以下のように書き替えられます。オペレータはpipe()メソッドの引数に渡してください。Observerは取りまとめ役のSubjectにサブスクライブします。SubjectがマルチキャストにしたいObservableにサブスクライブするのです。して、ObservableはSubjectの力を借りてマルチキャストすることになります。multicast()が返すのは、Observableを継承するConnectableObservableのオブジェクトです(第2引数がない場合。Secret」参照)。ConnectableObservable」参照)。ConnectableObservable.connect()メソッドが、登録されたObservableの実行を始めます。つぎのコードでメソッドの呼び出しは、内部的にobservable.subscribe(subject)と同じ役割を果たすのです。メソッドはSubscriptionを返しますので、Subscription.unsubscribe()で実行は取り消せます。参照を調べるマルチキャストにしたObservableに、複数のObserverで時間差の実行をしてみましょう。最初の実行でObserverが加えられたらconnect()を呼び出し、最後の実行を止めたときunsubscribe()で取り消します。そのために、connect()の戻り値は変数にとっておかなければなりません。unsubscribedマルチキャストのObservableにsubscribe()でObserverが加わったら値の受け取りを始め、すべてunsubscribe()されてObserverがなくなったら止めてしまえると便利でしょう。登録されている参照数を確かめて実行・停止するのがオベレータrefCount()です。Observableを返すので(新たなConnectableObservableをつくるのではありません)、そのオブジェクトにsubscribe()とunsubscribe()を行います。参照数が0より増えれば、内部的にconnect()が呼び出されます。0になれば実行を止めるのです。BehaviorSubjectSubjectのサブクラスのひとつBehaviorSubjectは、オブジェクトが現在値をもちます。直近に送られた値を納め、Observerが実行されると同時にBehaviorSubjectからその値を受け取るのです。つぎのコードでは、BehaviorSubjectに初期値0を与えて、オブジェクトがつくられます。すると、subscribe()で実行されたとき、ただちにObserverにはその値が送られるのです。つぎの実行でも、直近の値(2)を受け取ってから、next()で値が送られることになります。ReplaySubjectReplaySubjectは、送信済みの値がつぎの実行に送れるということはBehaviorSubjectと似ています。違いは、Observableに送った値を複数さかのぼって記録できることです。つぎのコードのように、ReplaySubjectはさかのぼる値の数(バッファーサイズ)を渡してつくります。5ReplaySubjectに記録する値の数を定めるのに、第1引数のバッファーサイズに加え、第2引数でさかのぼるウィンドウの時間をミリ秒で与えることができます。つぎのコードでは、第1引数(100)はあえて大きくしたうえで、第2引数のミリ秒(500)を狭めました。すると、ふたつ目の実行でObserverは、直近のその時間に送られた値だけさかのぼって受け取るのです。AsyncSubjectもうひとつご紹介するSubjectのサブクラスAsyncSubjectは、Observableを実行して最後の値だけがObserverに送られます。値を受け取るのは、complete()で実行が終わったときです。5AsyncSubjectの働きは、last()オペレータと似ています。last()は実行が終わるのを待って、最後の値だけを送ります。