jsイベントループ機構例解析

小云云
小云云オリジナル
2017-12-14 09:21:312550ブラウズ

この記事では主にjsのイベントループの仕組みを紹介し、例を通してjsの使い方やテクニックを分析していきますので、ぜひ皆さんも一緒にjsのイベントループの仕組みを活用してみてください。


var start = new Date()
setTimeout(function () {
 var end = new Date
 console.log('Time elapsed:', end - start, 'ms')
}, 500)
while (new Date() - start < 1000) {
}


目的の機能を実現できる他の言語はありますか? Java、Java.util.Timer では、スケジュールされたタスクのソリューションはマルチスレッドによって実装され、タスク オブジェクトはタスク キューに格納され、専用のスケジューリング スレッドが新しいサブスレッドでタスクの実行を完了します

js はシングルスレッドです

JavaScript の主な目的は、ユーザーと対話し、DOM を操作することです。これにより、シングルスレッドのみが可能であることが決まります。そうでない場合は、非常に複雑な同期の問題が発生します。

マルチコア CPU の計算能力を活用するために、HTML5 は Web Worker 標準を提案しています。これにより、JavaScript スクリプトは複数のスレッドを作成できますが、子スレッドはメインスレッドによって完全に制御され、DOM を操作してはなりません。したがって、この新しい標準は JavaScript のシングルスレッドの性質を変更しません。

関数呼び出しスタックとタスクキュー

呼び出しスタック

JSが実行されると、呼び出しスタックが形成され、関数が呼び出されるときに戻りアドレス、パラメータ、およびローカル変数がプッシュされます。実行中の関数で別の関数が呼び出された場合、関数の実行後に、その関数の関連する内容もスタックの先頭にプッシュされます。複合型の値もヒープに格納されるため、ポップアップされるのはポインターだけであり、その値はまだヒープ内にあり、

イベント ループとタスク キュー
によってリサイクルされます。

JavaScript メインスレッドには実行スタックとタスクキューがあります

非同期操作 (例: setTimeout、AJAX) が実行されると、これらのタスクが完了した後、ブラウザ (OS) によって非同期操作が実行されます。ブラウザは、メイン スレッドの実行スタックがクリアされると、事前に定義されたコールバック関数をメイン スレッドのタスク キューにプッシュし、タスク キューが読み取られるときに、そのコールバック関数を読み取ります。スレッドは実行を続けるため、無限ループに入ります。これがイベント ループです。

メイン スレッドの実行スタックとタスク キューが周期的に実行され、イベント ループが形成されます。

setTimeout() はイベントを挿入するだけです。 「タスクキュー」。メインスレッドが指定されたコールバックを実行する前に、現在のコード (実行スタック) が完了するまで待機する必要があります。現在のコードに時間がかかる場合は、長時間かかる可能性があるため、setTimeout() で指定された時間にコールバック関数が実行されることを保証する方法はありません。
別の例

(function test() {
 setTimeout(function() {console.log(4)}, 0);
 new Promise(function executor(resolve) {
 console.log(1);
 for( var i=0 ; i<10000 ; i++ ) {
 i == 9999 && resolve();
 }
 console.log(2);
 }).then(function() {
 console.log(5);
 });
 console.log(3);
})()


マクロタスクとマイクロタスク

マクロタスクとマイクロタスクは、非同期タスクの 2 つの分類です。タスクを一時停止するとき、JS エンジンはすべてのタスクをカテゴリに応じてこれら 2 つのキューに分割します。まず、最初のタスクがマクロタスク キューから取り出されます (このキューは実行後に取り出されます)。すべてのタスクが順番に実行され、その後マクロタスク タスクがフェッチされ、両方のキューのタスクがフェッチされるまでサイクルが再開されます。
マクロタスク: スクリプト (コード全体)、setTimeout、setInterval、setImmediate、I/O、UI レンダリング

マイクロタスク: process.nextTick、Promises (ここではブラウザーによって実装されたネイティブ Promise を指します)、Object.observe , MutationObserver


結論

すべてのコード (スクリプト) マクロタスク -> マクロタスク(setTimeout) -> Node.js のイベント ループ

process.nextTick & setImmediate

process.nextTickで指定されたタスクは常にすべての非同期タスクの前に発生します

setImmediateで指定されたタスクは常に次のイベントループで実行されます


process.nextTick(function A() {
 console.log(1);
 process.nextTick(function B(){console.log(2);});
});
setTimeout(function timeout() {
 console.log(&#39;TIMEOUT FIRED&#39;);
}, 0)

new Promise(function(resolve) {
 console.log(&#39;glob1_promise&#39;);
 resolve();
}).then(function() {
 console.log(&#39;glob1_then&#39;)
})
process.nextTick(function() {
 console.log(&#39;glob1_nextTick&#39;);
})

関連おすすめ:

フロントエンド上級(12):イベントループの仕組みを詳しく解説

div color_javascriptスキルを変更するjsループの具体的な方法

Node.jsイベントループチュートリアル

以上がjsイベントループ機構例解析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。