process.nextTickとsetImmediateの違い
自分的な結論
パフォーマンス上の問題が起きない限りは、setImmediate
を使っておくのが無難
process.nextTick
とsetImmediate
の違い
が素晴らしくまとまっているので、詳しくはコチラの記事を読んでいただきたいのですが、
ポイントを。
- process.nextTickを関数の中で再帰的に呼び出すとイベントループを止めてしまう
- process.nextTickの方がパフォーマンスはいいらしい
コード
'use strict'; const fs = require('fs'); console.log('start'); fs.readFile('./a.txt', (err, data) => { console.log('readFile'); process.nextTick(() => { console.log('readFile -> nextTick'); }); setImmediate(() => { console.log('readFile -> setImmediate'); }); }); process.nextTick(() => { console.log('nextTick'); fs.readFile('./a.txt', (err, data) => { console.log('nextTick -> readFile'); }); }); setImmediate(() => { console.log('setImmediate'); fs.readFile('./a.txt', (err, data) => { console.log('setImmediate -> readFile'); }); }); (function doNextTick(i) { console.log(`doNextTick ${i}`); if (i >= 5) { return; } i++; process.nextTick(() => { doNextTick(i); }); })(1); (function doSetImmediate(i) { console.log(`doSetImmediate ${i}`); if (i >= 5) { return; } i++; setImmediate(() => { doSetImmediate(i); }); })(1); (function doNextTick2(i) { console.log(`doNextTick2 ${i}`); if (i >= 5) { return; } i++; process.nextTick(() => { doNextTick2(i); }); })(1);
実行結果
start doNextTick 1 doSetImmediate 1 doNextTick2 1 nextTick doNextTick 2 doNextTick2 2 doNextTick 3 doNextTick2 3 doNextTick 4 doNextTick2 4 doNextTick 5 doNextTick2 5 readFile readFile -> nextTick nextTick -> readFile setImmediate doSetImmediate 2 readFile -> setImmediate setImmediate -> readFile doSetImmediate 3 doSetImmediate 4 doSetImmediate 5
結果
- 再帰関数である、doNextTickとdoNextTick2が終わるまでreadFileが呼び出されない。イベントループをブロックしてしまっている
- setImmediateは↑のjxckさんの参考記事の図の通り、IOイベント終了後に呼び出されているよう。イベントループをブロックしていない
まとめ
この辺の挙動を知らないでprocess.nextTick
を使うと痛い目にあう可能性があります。
きちんと用法用量を守って使う、自信なければsetImmediate
にしといた方がいいというのが自分的な結論です