概念の実装に関連する1、ランタイムの概要
Javascript
ベースがありEvent Loop
、同時実行モデルイベントループは、
以下は、現代のブラウザのJavaScriptエンジンの実装の仕組みを説明し、単語の意味記述のいくつかを説明する理論モデルを説明します。
ビジュアルモデルは表します。
スタックスタック
関数呼び出しスタックフレームを形成します
function foo(b) {
var a = 10;
return a + b + 11;
}
function bar(x) {
var y = 3;
return foo(x * y);
}
console.log(bar(7)); // 返回 42
复制代码
関数呼び出しの下に簡単な手順:
呼び出されたときbar(7)
、第一の確立がstack frame
あるbar
(パラメータ含まれている7
場合、およびローカル変数)をbar
呼び出しfoo
時間は、第二の確立することstack frame
であるfoo
(パラメータ含ま3* 7
とローカル変数)とに配置され、すなわち、。bar
上方
栈的顶部
場合foo(21)
リターン42仕上げfoo
のみ残して、スタックフレームが離れて除去されbar(7)
、その後、実行bar
、復帰後、全体のスタックが空です。
ヒープヒープ
オブジェクトが関連付けられているHeap
、すなわち、大きな構造化されていないメモリ領域を示すために、それ。
キューキュー
Javascript
メッセージキューのランタイムを保留中の一連のメッセージを使用します。各メッセージは、メッセージを処理する機能と関連付けられています。
イベントサイクルのいくつかの時間で运行时从最先进入队列的消息开始处理队列中的消息
。そうするために、メッセージは呼び出し元の関数は、それに関連する入力パラメータとして、キューから削除されます。前述したように、関数は常にスタックフレームの作成のために呼び出します。
していきます関数の実行stack
空になります。次のメッセージは、メッセージキューニュースイベントループがあるが実行される場合は、メッセージキュー。
2、イベントループイベントループ
道の彼は次のことを実現するために実行されるので、それは、イベントループと呼ばれています。
while (queue.waitForMessage()) {
queue.processNextMessage();
}
复制代码
メッセージがない場合、queue.waitForMessage()
それはメッセージの到着を待つを同期されます。
ランに-完了最後まで実行
各メッセージの端部が完全に実施された後、実装プロセスは、次のメッセージを戻ります。
他のコードが実行される前に関数を実行するたびに、先取りされず、それが完全に実装されていたであろう(と操作の数の機能を変更することができます):これは、以下を含むいくつかの優れた特性解析プログラムを提供しています。
C言語と機能は、1つのスレッドで実行される場合、例えば、いくつかの時間のために、システムは、別のスレッド割り込みに他のコードの実装によって実行される同じではありません。
このモデルの欠点は、メッセージの実行に時間がかかりすぎるだろうというとき、Webユーザは、次のようないくつかに対処することはできませんclick
、srcoll
インタラクティビティ。ブラウザがポップアップ表示されます“a script is taking too long to run”
。このような状況を緩和するために、このダイアログを。良い解決策は、にあります缩短消息处理的时间,或者把一个消息分割成多个消息
。
メッセージを追加すると、メッセージを追加します。
内部のWebブラウザーで只要有事件发生并且有监听器绑定的时候,一定会增加一个消息
。何のリスナーが存在しない場合、イベントは消失しました。だから、要素をクリックして、イベントハンドラをクリックすると、メッセージキューにメッセージを追加します。
:setTimeout関数は、2つのパラメータを取る添加队列的消息
と时间(默认 0 )
、この時間値は、メッセージが最小遅延時間のメッセージキューに追加される表します。メッセージキュー場合は、他のメッセージ、遅延時間が経過した後にこのメッセージは、すぐに処理されません。メッセージキューは、他のニュースを持っている場合は、setTimeout
ニュースが実行するように対処するために別のメッセージまで待たなければなりません。このため、2番目のパラメータは示して最小的时间间隔
しばらく非确切的时间
。
第二引数の有効期限は、setTimeoutメソッドが実行されていない場合、示しています。
const s = new Date().getSeconds();
setTimeout(function() {
// prints out "2", meaning that the callback is not called immediately after 500 milliseconds.
console.log("Ran after " + (new Date().getSeconds() - s) + " seconds");
}, 500);
while(true) {
if(new Date().getSeconds() - s >= 2) {
console.log("Good, looped for 2 seconds");
break;
}
}
复制代码
ゼロは、ゼロ遅延を遅らせます
ゼロ遅延は0ミリ秒後に実行されるコールバック関数の真の代表ではありません。
所定の時間間隔後にゼロ遅延のsetTimeoutコールバック関数を実行しません。
これは、キュー内のメッセージの数がタスクの実行を待っているかどうかによって異なります。
例えば:
(function() {
console.log('this is the start');
setTimeout(function cb() {
console.log('Callback 1: this is a msg from call back');
});
console.log('this is just a message');
setTimeout(function cb1() {
console.log('Callback 2: this is a msg from call back');
}, 0);
console.log('this is the end');
})();
// "this is the start"
// "this is just a message"
// "this is the end"
// 当前函数 note that function return, which is undefined, happens here
// "Callback 1: this is a msg from call back"
// "Callback 2: this is a msg from call back"
复制代码
プロセスのみゼロ遅延最小要求遅延が正確な時間を保証されないためである補正後、それは、ステージを印刷する前に補正出力である「これは単なるメッセージです」。
一般的には、コードが実行された後、キューで待機するのsetTimeoutは、他のすべてのメッセージ、あなたが特定の時間間隔を設定する瞬間を実行します。
ます。https://juejin.im/post/5cfb7551e51d4510a37babbaで再現