[解決済み] nextTickとsetImmediateの比較、ビジュアル解説
質問
nextTickとsetImmediateの違いについて、とても混乱しています。インターネット上でそれらに関するすべてのドキュメントを読みましたが、それらがどのように機能するのかまだ理解していません。
例を挙げます。
function log(n) { console.log(n); }
setImmediate
setImmediate(function() {
setImmediate(function() {
log(1);
setImmediate(function() { log(2); });
setImmediate(function() { log(3); });
});
setImmediate(function() {
log(4);
setImmediate(function() { log(5); });
setImmediate(function() { log(6); });
});
});
//1 2 3 4 5 6
ネクストティック
process.nextTick(function() {
process.nextTick(function() {
log(1);
process.nextTick(function() { log(2); });
process.nextTick(function() { log(3); });
});
process.nextTick(function() {
log(4);
process.nextTick(function() { log(5); });
process.nextTick(function() { log(6); });
});
});
//1 4 2 3 5 6
なぜこのような結果になるのでしょうか?視覚的に、あるいは非常にわかりやすい説明で説明してください。nodeのコア開発者でさえ、nextTickとsetImmediateが人々にどのように理解されるべきかについて同意していません。
ソースはこちらです。
どのように解決するのですか?
次の2つの例を考えてみましょう。
setImmediate
setImmediate(function A() {
setImmediate(function B() {
log(1);
setImmediate(function D() { log(2); });
setImmediate(function E() { log(3); });
});
setImmediate(function C() {
log(4);
setImmediate(function F() { log(5); });
setImmediate(function G() { log(6); });
});
});
setTimeout(function timeout() {
console.log('TIMEOUT FIRED');
}, 0)
// 'TIMEOUT FIRED' 1 4 2 3 5 6
// OR
// 1 'TIMEOUT FIRED' 4 2 3 5 6
ネクストティック
process.nextTick(function A() {
process.nextTick(function B() {
log(1);
process.nextTick(function D() { log(2); });
process.nextTick(function E() { log(3); });
});
process.nextTick(function C() {
log(4);
process.nextTick(function F() { log(5); });
process.nextTick(function G() { log(6); });
});
});
setTimeout(function timeout() {
console.log('TIMEOUT FIRED');
}, 0)
// 1 4 2 3 5 6 'TIMEOUT FIRED'
setImmediateコールバックはイベントループから、キューに入れられた順番に反復ごとに一度だけ起動されます。つまり、イベントループの最初の繰り返しで、コールバックAが起動されます。次に、イベントループの2回目の繰り返しでコールバックBが起動され、イベントループの3回目の繰り返しでコールバックCが起動される、といった具合です。これにより、イベントループがブロックされるのを防ぎ、その間に他のI/Oやタイマーのコールバックを呼び出すことができます(ループの1回目または2回目の繰り返しで起動される0msタイムアウトの場合と同様です)。
しかし、nextTickコールバックは、常に現在のコードが実行された直後、イベントループに戻る前に起動されます。nextTick の例では、イベント ループに戻る前にすべての nextTick コールバックを実行することになります。setTimeoutのコールバックはイベントループから呼び出されるため、すべてのnextTickコールバックが終了するまで、「TIMEOUT FIRED」というテキストは出力されません。
関連
-
[解決済み】AWS STS AssumeRoleへのアクセスを可能にする方法
-
[解決済み】Node Version Manager のインストール - nvm コマンドが見つかりません。
-
[解決済み】モジュール '@babel/core' が見つかりません。
-
[解決済み] Expectアサーションの型エラー -> expect(...).toExistは関数ではない
-
[解決済み] nodeファイルの先頭にある"/usr/bin/env node "は、具体的には何をするのですか?
-
[解決済み] AWS s3 api error: specified bucket does not exist.
-
[解決済み] Npmエラー - Windows NT - 解決方法
-
[解決済み】setImmediateとnextTickの比較
-
[解決済み】Visual Studio CodeでJavaScriptを実行する
-
[解決済み] NodeJS - setTimeout(fn,0) vs setImmediate(fn)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】モジュール 'internal/util/types' が見つかりません。
-
[解決済み】Express.js req.bodyが未定義です。
-
[解決済み】MongoDBでコレクションを日付で並べ替えるには?
-
[解決済み】Nodejsの解決方法:Error: ENOENT: そのようなファイルまたはディレクトリがありません
-
[解決済み】Mongooseで、日付でソートするにはどうしたらいいですか?(node.js)
-
[解決済み] bodyParser は非推奨です express 4
-
[解決済み] エラーメッセージ MongoError: bad auth URI 文字列で認証に失敗しました。
-
[解決済み] Macでポート3000をロックしているプロセスを見つける(そして殺す)【終了
-
[解決済み] npm not able to find a fileに関連するエラーは何が原因でしょうか?node_modules サブフォルダ内にコンテンツがありません。なぜでしょうか?
-
[解決済み】setImmediateとnextTickの比較