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