当社では、JavaScriptの大きな特徴は、シングルスレッドであることを知っており、このスレッドは、唯一のイベントループを持っています。その実行順序機能を取得するだけでなく、いくつかの追加のコードを実行得るためにタスクキュー(タスクキュー)に依存することに加えて、JavaScriptのコード実行、関数呼び出しスタック。
キューデータ構造
- スレッドは、イベントループはユニークですが、タスクは複数のキューを持つことができます。
- タスクキューは、最新の規格では、マクロタスク(マクロタスク)とマイクロタスク(マイクロタスク)に分割され、それらはタスクとジョブと呼ばれています。
- おそらくあって、マクロタスク:スクリプト(全コード)、のsetTimeout、のsetInterval、setImmediate、I / O、UIのレンダリング。
- マイクロタスクは約含まれています:process.nextTick、約束、Object.observe(廃止)、MutationObserver(HTML5の新機能)
- setTimeout /約束し、私たちは、タスクのソースを呼び出します。タスクキューに、割り当てられた特定のタスクです。
- シーケンスマクロタスク実行キュー:スクリプト(全体的なコード) - >のsetTimeout(のsetInterval相同性) - > setImmediateの
マイクロタスクキューの実行順序:process.nextTick->約束(当時)
タスクを実行するためのsetTimeout、それはまだ関数呼び出しスタックを用いて行われ、タスクが対応するキューに配布されるタスクのディスパッチャに遭遇しています。
すべてのタスクが完了した後にのみ、再びマイクロタスクキューを開始しますのsetTimeout。そして、すべての実行可能なマイクロタスクをクリアします。
完成されたマイクロsetTiemoutキュータスクを生成した後、当時のループはsetImmediateキューを開始します。それはまだタスク実行キューsetImmediateはまず終了し、その後、生成されたマイクロタスクを実行しています。
キューが生成された実行setImmediateマイクロは、すべてのタスクを実行すると、サイクルの第2ラウンドが終わりました。
ここでは、サイクルタイムのノードの終わりに注意する必要があります。
我々はsetTimeoutメソッドのsetTimeoutタスクの実装に遭遇したとき、それはまだ行くためにタスクキューを対応のsetTimeoutに配布されますが、タスクはイベントループの次のラウンドが実行されるまで待たなければなりません。ケースは、このような複雑なネストを伴わない、我々は、追加または変更サイクルを感じるように自分の位置を変更するために始めることができます。
例1:
console.log('golb1');
setTimeout(function() {
console.log('timeout1');
process.nextTick(function() {
console.log('timeout1_nextTick');
})
new Promise(function(resolve) {
console.log('timeout1_promise');
resolve();
}).then(function() {
console.log('timeout1_then')
})
})
setImmediate(function() {
console.log('immediate1');
process.nextTick(function() {
console.log('immediate1_nextTick');
})
new Promise(function(resolve) {
console.log('immediate1_promise');
resolve();
}).then(function() {
console.log('immediate1_then')
})
})
process.nextTick(function() {
console.log('glob1_nextTick');
})
new Promise(function(resolve) {
console.log('glob1_promise');
resolve();
}).then(function() {
console.log('glob1_then')
})
setTimeout(function() {
console.log('timeout2');
process.nextTick(function() {
console.log('timeout2_nextTick');
})
new Promise(function(resolve) {
console.log('timeout2_promise');
resolve();
}).then(function() {
console.log('timeout2_then')
})
})
process.nextTick(function() {
console.log('glob2_nextTick');
})
new Promise(function(resolve) {
console.log('glob2_promise');
resolve();
}).then(function() {
console.log('glob2_then')
})
setImmediate(function() {
console.log('immediate2');
process.nextTick(function() {
console.log('immediate2_nextTick');
})
new Promise(function(resolve) {
console.log('immediate2_promise');
resolve();
}).then(function() {
console.log('immediate2_then')
})
})
例2:
setTimeout(function() {
console.log(1);
setTimeout(function() {
console.log(2);
}, 0);
process.nextTick(function() {
console.log(5);
process.nextTick(function() {
console.log(6);
});
});
}, 0);
process.nextTick(function() {
console.log(3);
process.nextTick(function() {
console.log(4);
});
setTimeout(function() {
console.log(7);
}, 0);
});
結果:3417562