`setImmediate()` を理解する

できるだけ早く、非同期的にコードを実行したい場合、Node.js が提供する `setImmediate()` 関数を使用するという選択肢があります。

setImmediate(() => {
  // run something
});

`setImmediate()` の引数として渡された関数は、イベントループの次のイテレーションで実行されるコールバックです。

`setImmediate()` は `setTimeout(() => {}, 0)` (0ミリ秒のタイムアウトを渡す) と、`process.nextTick()` と `Promise.then()` とどう違うのでしょうか?

`process.nextTick()` に渡された関数は、現在の操作が終了した後、イベントループの現在のイテレーションで実行されます。つまり、常に `setTimeout` と `setImmediate` の前に実行されます。

0ミリ秒の遅延を持つ `setTimeout()` コールバックは、`setImmediate()` と非常によく似ています。実行順序はさまざまな要因によって異なりますが、どちらもイベントループの次のイテレーションで実行されます。

`process.nextTick` コールバックは `process.nextTick` キューに追加されます。 `Promise.then()` コールバックは `promises microtask` キューに追加されます。 `setTimeout`、`setImmediate` コールバックは `macrotask` キューに追加されます。

イベントループは、最初に `process.nextTick` キューのタスクを実行し、次に `promises microtask` キューを実行し、最後に `macrotask` キューを実行します。

`setImmediate()`、`process.nextTick()`、`Promise.then()` の順序を示す例を以下に示します。

const baz = () => console.log('baz');
const foo = () => console.log('foo');
const zoo = () => console.log('zoo');

const start = () => {
  console.log('start');
  setImmediate(baz);
  new Promise((resolve, reject) => {
    resolve('bar');
  }).then(resolve => {
    console.log(resolve);
    process.nextTick(zoo);
  });
  process.nextTick(foo);
};

start();

// start foo bar zoo baz

このコードは、最初に `start()` を呼び出し、次に `process.nextTick` キューにある `foo()` を呼び出します。その後、`promises microtask` キューを処理し、`bar` を出力し、同時に `process.nextTick` キューに `zoo()` を追加します。次に、追加されたばかりの `zoo()` を呼び出します。最後に、`macrotask` キューにある `baz()` が呼び出されます。

読書時間
2分
貢献する
このページを編集