JavaScript Event Loopの概要
3394 ワード
最近、
クライアントの
質問シーン
まずコードを見てみましょう.
上のコードは主に1つの机能を完成したいです:ボタンがクリックされた时------>1つの状态を表示してユーザーにいくつかの事をしていることを知らせます------>仕事を始めます------>仕事が终わった后に状态はすでに完成しましたに変更します.
問題ないように見えますが、仕事ができるはずなので、ブラウザでこのページを実行します.しかし、現実はいつも残忍で、予想された効果に合っていない.ボタンをクリックするとブラウザがフリーズし、表示状態の
その原因を究明します:JavaScriptエンジンは単一のスレッドのです.この場合、ブラウザカーネルにどのような主要な常駐スレッドがあるのかを理解してこそ、上記の疑問を解くことができる.ブラウザカーネル常駐スレッドには、次のようなものがあります.ブラウザGUIレンダリングスレッド JavaScriptエンジンスレッド ブラウザタイミングトリガスレッド ブラウザイベントトリガスレッド ブラウザhttp非同期要求スレッド 一方、GUIレンダリングスレッドとJavaScriptエンジンスレッドは反発し、JavaScript実行時にGUIレンダリングスレッドは保留され、ページはすべての解析とレンダリング動作を停止します.上記の3、4、5クラスのスレッドでも異なる非同期イベントが発生します.次の図を見ると直感的に見えるはずです.
JavaScript-Event-Loop
JavaScriptエンジンは単一スレッドなので、コードはキューに押され、エンジンが先進的な先発方式で実行されます.イベント処理関数、timer実行関数もこのキューに並べられ、無限ループを利用してキューヘッダから関数を取り出して実行されます.これが
次に、上記のコードがなぜ予想された効果に達しなかったのかを図で説明し続けます.
すると結局「done」しか見えませんでした.
どうやって解決しますか?
どうしてこれで解決したのですか.やはり上のキューの図で説明します.
JavaScript
Nodejs
を学ぶ過程で
という概念を深く理解し、Nodejs
をよりよく使用するために、これらの概念は知られていない.以前はJavaScript
のユーザーとして機能していたが、どのように動作しているのかは全く分からず、多くの概念に対しても「その理由を知っている」.クライアントの
JavaScript
とNodejs
にとってはそれほど差はありませんが、今回はクライアント側からEvent Loop
という概念についてお話ししましょう.
の切り込み点の一つでしょう.実はjQuery
の作者John Resigは数年前に良い文章How JavaScript Timers Workを書いて、timer
と
がブラウザの中でどのように働いているのかを述べて、私もこの文章を通じてやっと“その理由を知っています”.質問シーン
まずコードを見てみましょう.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<a href="#" id="doBtn">do something</a>
<div id="status"></div>
<script type="text/javascript">
void function() {
var doBtn = document.getElementById('doBtn')
, status = document.getElementById('status');
doBtn.onclick = function(e) {
e.preventDefault();
status.innerText = 'doing...please wait...'; //
sleep(10000); // ,10s
status.innerText = 'done'; //
};
}();
function sleep(ms) {
var start = new Date();
while (new Date() - start <= ms) {}
}
</script>
上のコードは主に1つの机能を完成したいです:ボタンがクリックされた时------>1つの状态を表示してユーザーにいくつかの事をしていることを知らせます------>仕事を始めます------>仕事が终わった后に状态はすでに完成しましたに変更します.
問題ないように見えますが、仕事ができるはずなので、ブラウザでこのページを実行します.しかし、現実はいつも残忍で、予想された効果に合っていない.ボタンをクリックするとブラウザがフリーズし、表示状態の
div
は表示されず、インタフェースにも「doing...」は表示されません.このヒント;10s
を経過した後、ブラウザは気を取り戻し、時間のかかる計算が終了したことを表し、このとき表示状態に使用されるdiv
は「done」を表示する.その原因を究明します:JavaScriptエンジンは単一のスレッドのです.この場合、ブラウザカーネルにどのような主要な常駐スレッドがあるのかを理解してこそ、上記の疑問を解くことができる.ブラウザカーネル常駐スレッドには、次のようなものがあります.
JavaScript-Event-Loop
JavaScriptエンジンは単一スレッドなので、コードはキューに押され、エンジンが先進的な先発方式で実行されます.イベント処理関数、timer実行関数もこのキューに並べられ、無限ループを利用してキューヘッダから関数を取り出して実行されます.これが
Event Loop
です.次に、上記のコードがなぜ予想された効果に達しなかったのかを図で説明し続けます.
すると結局「done」しか見えませんでした.
どうやって解決しますか?
setTimeout()
を使用します.次に、変更されたonclick
イベント処理関数を示します.1
2
3
4
5
6
7
8
9
10
doBtn.onclick = function(e) {
e.preventDefault();
status.innerText = 'doing...please wait...'; //
setTimeout(function() {
sleep(10000); // ,10s
status.innerText = 'done'; //
}, 0); // 0ms delay
};
どうしてこれで解決したのですか.やはり上のキューの図で説明します.
JavaScript