Skip to content

タスクとスケジューラーの基礎知識

同期処理とは

同期処理は、コードが記述された順番に即座に実行され、前の処理が終わるまで次の処理に進みません。

ts
console.log('A');
console.log('B');
console.log('C');

// 出力:
// A
// B
// C

非同期処理とは

非同期処理は、すぐに実行されず、現在の同期処理が終わった後に実行される処理です。 非同期処理には「マクロタスク」と「マイクロタスク」が存在します。

マクロタスク

  • イベントループの次のサイクルで実行されるタスク。
  • 例: setTimeout, setInterval, ブラウザイベント

実行例

ts
console.log('Start');
setTimeout(() => console.log('Macro Task'), 0);
console.log('End');

// 出力:
// Start
// End
// Micro Task

RxJSにおける対応

  • asyncScheduler
    • 内部でsetTimeoutを使用
    • マクロタスクとして動作
ts
import { of, asyncScheduler } from 'rxjs';
import { observeOn } from 'rxjs/operators';

of('Hello')
  .pipe(observeOn(asyncScheduler))
  .subscribe(console.log);

// 出力:
// Hello

マイクロタスク

  • 現在のタスクが終了した直後に、次のタスクが始まる前に実行されるタスク。
  • 例: Promise.then, queueMicrotask

実行例

ts
console.log('Start');
Promise.resolve().then(() => console.log('Micro Task'));
console.log('End');

// 出力:
// Start
// End
// Micro Task

RxJSにおける対応

  • asapScheduler
    • 内部でPromise.resolve().then()を使用
    • マイクロタスクとして動作
ts
import { of, asapScheduler } from 'rxjs';
import { observeOn } from 'rxjs/operators';

of('Hi')
  .pipe(observeOn(asapScheduler))
  .subscribe(console.log);

// 出力:
// Hi

同期タスク

  • すぐに実行される通常のコード。

RxJSにおける対応

  • queueScheduler
    • 同期的に見えるが、タスクキューイングにより細かい制御が可能。
ts
import { of, queueScheduler } from 'rxjs';
import { observeOn } from 'rxjs/operators';

of('Now')
  .pipe(observeOn(queueScheduler))
  .subscribe(console.log);

// 出力:
// Now

実行順序まとめ

コード例

ts
console.log('1');

setTimeout(() => console.log('2 (setTimeout)'), 0);
Promise.resolve().then(() => console.log('3 (Promise)'));

console.log('4');

// 出力:
// 1
// 4
// 3 (Promise) 👈 マイクロタスク
// 2 (setTimeout) 👈 マクロタスク

タスクとRxJSスケジューラー対応表

種類RxJSスケジューラー
同期処理通常のコードqueueScheduler
マイクロタスクPromise.then, queueMicrotaskasapScheduler
マクロタスクsetTimeout, setIntervalasyncScheduler

Released under the CC-BY-4.0 license.