ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScriptにおけるイベントループ(Event Loop)の実行シーケンス

JavaScriptにおけるイベントループ(Event Loop)の実行シーケンス

不言
不言転載
2018-10-27 14:00:102570ブラウズ

この記事はJavaScriptにおけるイベントループ(Event Loop)の実行シーケンスに関するものなので、困っている方は参考にしていただければ幸いです。

簡単な紹介: EvenLoop キュー内の Promise.resove、setTimeout、setImmediate、process.nextTick の実行順序について説明します

問題の原因

イベント ループは、

例1:

setTimeout(function(){console.log(1)},0);

console.log(2)

//输出2,1

など、「タスク キュー」から周期的にタスクを読み取るメイン スレッドを指します。上の例では、同期タスクがメインスレッドが最初に実行され、メインスレッドがスレッドタスクを実行した後、イベントループからタスクが読み込まれるため、最初に2が出力され、次に1が出力されます。

イベント ループがタスクを読み取る順序は、タスク キュー (ジョブ キュー) 内のさまざまなタスク読み取りルールの制限によって異なります。たとえば、次の例では、

例2:

setTimeout(function () {
  console.log(3);
}, 0);

Promise.resolve().then(function () {
  console.log(2);
});
console.log(1);
//输出为  1  2 3

出力 1 が最初に実行されます。メインスレッドで同期タスクが最初に実行されるため、問題はありません。ここで問題となるのは、setTimeout と Promise の実行優先順位です。次にタスクが定義されます。

実行順序

ジョブ キュー内のキューは、マクロタスクとマイクロタスクの 2 種類に分けられます。実行順序の規則を見てみましょう。

macro-task队列包含任务: a1, a2 , a3
micro-task队列包含任务: b1, b2 , b3

の実行順序が次のとおりであると仮定します。まず、マルコタスク キューの先頭のタスク、つまり a1 (a1) を実行します。は同期のメインタスクを表します) タスクの実行が完了したら、マイクロタスクキュー内のすべてのタスクを実行します。つまり、b1、b2、b3 を (非同期的に) 実行します。実行後、マイクロタスク内のタスクをクリアし、タスク内の 2 番目のタスク (非同期) を順番にループします。

マクロタスクキューとマイクロタスクキューの実行順序を理解した後、実際のシナリオでこれら 2 種類のキューに実際に含まれるタスクを見てみましょう (例としてノード V8 エンジンを取り上げます)。ノード V8 では、これら 2 つのタイプの実際のタスク順序は次のとおりです。

マクロタスク キューには実際にタスクが含まれます:

script(主程序代码)[对应上方的a1],setTimeout, setInterval, setImmediate, I/O, UI rendering

マイクロタスク キューには実際にタスクが含まれます:

process.nextTick, Promises, Object.observe, MutationObserver

これから得られる実行順序は次のようになります:

script(主程序代码)—>process.nextTick—>Promises...——>setTimeout——>setInterval——>setImmediate——> I/O——>UI rendering

ES6 では、マクロタスク キューは ScriptJobs とも呼ばれ、マイクロタスクは PromiseJobs

Example

(1) setTimeoutとpromise

例3:

setTimeout(function () {
  console.log(3);
}, 0);

Promise.resolve().then(function () {
  console.log(2);
});

console.log(1);

(2) process.nextTickとpromise、setTimeout

例子4:
setTimeout(function(){console.log(1)},0);

new Promise(function(resolve,reject){
   console.log(2);
   resolve();
}).then(function(){console.log(3)
}).then(function(){console.log(4)});

process.nextTick(function(){console.log(5)});

console.log(6);
//输出2,6,5,3,4,1

(3) より複雑な例

setTimeout(function(){console.log(1)},0);

new Promise(function(resolve,reject){
   console.log(2);
   setTimeout(function(){resolve()},0)
}).then(function(){console.log(3)
}).then(function(){console.log(4)});

process.nextTick(function(){console.log(5)});

console.log(6);

//输出的是  2 6 5 1 3 4

これらの例はご判断ください。実行順序に従って理由を説明します。ここでは 1 つずつ説明しません。

以上がJavaScriptにおけるイベントループ(Event Loop)の実行シーケンスの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。