6.2.1Schedulerは、オペーレータがサブスクリプションをいつ開始し、通知はいつ送るのかコントロールします。サブスクリプションや通知が、どのコンテキストで行われるのかをスケジュールできるのです。GitHubのReactiveX/rxjs「Scheduler」を下じきに、サンプルコードや解説は改めました。Schedulerの機能Schedulerは、サブスクリプションをいつ開始し、通知はいつ送るのかコントロールします。構成要素となるのはつぎの3つです。タスクをどのように保持し、キューに入れるのか、優先度やその他の基準にもとづいて定める。タスクが実行される場所と時期を決める。実行するか、setTimeout()やprocess.nextTick()などのコールバックの仕組みを使うか、あるいはアニメーションフレームにもとづくか。Schedulerのgetterメソッドnow()により、時間の概念が与えられる。Schedulerにスケジューリングされたタスクは、そのクロックの示す時間にのみしたがう。Schedulerを用いることによって、どの実行コンテキストでObservableがObserverに通知を送るが決まるのです。Schedulerは使わないコードの実行結果をみておきましょう。Observableは値を同期的に送ります。subscribeObservableにobserveOn()オペレータでasyncSchedulerを定めると、値が非同期で送られるようになります。具体的には、observeOn()に渡したasyncSchedulerは、内部的にschedule()メソッドが呼び出され、Observerに実行の遅れ(delay)を与えます。デフォルト値は0です。待ち時間0はsetTimeout()やsetInterval()の仕組みで扱われ、イペントループのつぎの繰り返しで実行されるため、同期処理には遅れる結果となります。3doneobserveOn(asyncScheduler)は、Observableと最終Observerとの間に、つぎのような構造のプロキシObserverをつくるのです。送られる値);},}Schedulerのschedule()メソッドの引数となる遅れ(delay)は、自身の内部クロックが測る時間にもとづきます。現実の時計の時間が過ぎるのとは別です。時間に関わるオペレータは、遅れなど時間の経過をSchedulerのクロックにもとづいて扱います。同期的なタスクを実行する場合のテストでも、内部クロックにより時間が組み替えられるので便利です。Schedulerの種類asyncSchedulerは、RxJSが提供する組み込みスケジューラのひとつです。したスケジューラは、Schedulerオブジェクトの静的プロパティがつくって返します。Schedulerを渡さないと、通知が同期的かつ再帰的に送られる。決まった時間間隔あるいは末尾再帰の操作に用いられる。繰り返し操作に用いられる。マイクロタスクキューにスケジュールを加える。WorkerのMessageChannelあるいはsetTimeout()など利用できる中からもっとも速い配信の仕組みが用いられる。setInterval()によるスケジュールに加える。時間軸にもとづく操作に用いられる。ブラウザコンテンツが再描画される直前にスケジュールされる。スムーズなブラウザアニメーションに用いられる。Schedulerを使うRxJSコードでSchedulerをとくに定めなくても、実際には使われていることがあります。並行処理を扱うObservableのオペレータは、すべてSchedulerが選べるからです。Schedulerが与えてられていない場合、RxJSは最小並行性の原則にもとづいてデフォルトを決めます。オペレータの求める並行処理をもっとも少なくするSchedulerが選ばれるということです。メッセージの数が少ないObservableのオペレータには、RxJSはSchedulerを使いません。nullまたはundefinedです。逆に、大量あるいは回数のかぎられないメッセージを返すオペレータなら、queueSchedulerが用いられます。タイマーを使うオペレータが選ぶのはasyncSchedulerです。RxJSは、並行性がもっとも少ないSchedulerを用います。パフォーマンスを考えて、並行処理を取り入れるために、別のSchedulerを選ぶことも可能です。Observableをつくる関数には、引数にSchedulerを指定できるものがあります。from()関数は、第2引数にSchedulerが与えられます。Schedulerを引数にとる関数たとえば、from()関数は、つぎのような構文で、配列から変換された通知を送るときのSchedulerが定められます。通常、Schedulerは、関数の最後の引数とされます。以下に掲げたのは、Schedulerを引数にとる関数です。scheduler)bindCallback()bindNodeCallback()combineLatest()concat()empty()from()fromPromise()interval()merge()of()range()throw()timer()subscribeOn()オペレータsubscribeOn()オペレータは、subscribe()がどのコンテキストで呼び出されるのかをスケジュールするために用います。デフォルトでは、subscribe()の呼び出しは、同期的でただちに行われます。subscribeOn(()の引数にSchedulerを渡せば、実際のサブスクリプションは遅らせたり、スケジュールすることもできるのです。observeOn()オペレータobserveOn()オペレータは、前述01「Schedulerの機能」の例のように、通知がどのコンテキストで送られるのかをスケジュールするために用います。observeOn()は、もとのObservableと最終Observerとの中継のObserverを組み入れます。最終的なObserverは、引数のSchedulerにもとづいて呼び出されるのです。Schedulerを引数にとるオペレータ以下の時間に関わるオペレータは、最後の引数がSchedulerです。省くと、デフォルトのasyncSchedulerで処理を行います。bufferTime()debounceTime()delay()auditTime()sampleTime()throttleTime()timeInterval()timeout()timeoutWith()windowTime()他にSchedulerを引数にとる関数やオペレータは、以下のとおりです。combineLatest()concat()expand()merge()publishReplay()startWith()publishReplay()にSchedulerが与えられるのは、ReplaySubjectクラスを利用するためです。このクラスのコンストラクタには、最後の引数としてSchedulerが与えられます。ReplaySubjectは時間を扱うので、Schedulerのコンテキストにもとづくことになるのです。デフォルトでは、ReplaySubjectクラスがクロックを定めるのに用いるのはqueueSchedulerです。Schedulers」の項では、cache()オペレータを採り上げて説明しています。cache()はバージョン5.0.0-rc.1で除かれています。