js非同期入門から放棄(一)-Event Loopモデル
前言
非同期はずっと先端開発の中で最も頭を悩ませる難点であり、次のいくつかの文章は、この話題をめぐって展開される.
1.単一スレッドの言語-JavaScript
JSの当初の目的はブラウザのユーザインタラクションとDOM操作を扱うことであることはよく知られているが,JSが同時に2つ以上のスレッドが存在することを許可するように設計されている場合,以下のような問題が発生する.
2つのスレッドが同じDOMノード(aスレッドはノードを編集し、bスレッドはノードを削除する)を同時に操作すると、ブラウザはどのスレッドを基準にしているか判断できないため、処理できません.したがって,JSは単一スレッドのみである.(Web Worker APIはマルチスレッドを提供しているが、マルチコアcpuを使用する計算能力に純粋に基づいており、その作成されたサブスレッドはJS単一スレッドの設計実質に影響を及ぼさず厳格に制御されている)、単一スレッドの設計は、タスクがキューに並ぶように実行されることを意味する.
単一スレッド設計に基づいて、タスク自体が複雑すぎて処理しにくいのではなく、入力出力が遅すぎる(例えばAjaxがデータを取得する)場合が避けられません.一方,入出力待ちの間は,CPUはアイドル状態であり,リソースを十分に利用するために一時停止を許容し,結果が出てから実行するタスクを許可するように設計されている.
同期タスクと非同期タスクの2つのタスクがあります.
次にJSの処理メカニズムを紹介します.
2. Event Loop
りろんきそ
まずMDNからの図を見てみましょう.
スタック(stack)、関数呼び出しスタック.
この例を見てください.
function a(){
console.log('a')
}
function b(){
console.log('from')
a() // a
}
b()
はChromeで実行され、単一のステップでデバッグされます.次のステップが表示されます.b()
を実行すると、関数bが図1のようにスタックb
で関数a
を呼び出すと、a
は、図2のようにスタック(この部分の内容は,実際には,以前に紹介した閉パケット時の関数作用ドメインチェーンの生成部分,転送ゲートに対応している)
スタック(heap)、オブジェクトを格納するメモリ領域.(これは今のところ重要ではありません.
キュー(queue)、処理対象メッセージキュー、
各メッセージには、このメッセージを処理するための関数が関連付けられています.
一般的な例:
handleClick
関数がトリガーされ、ユーザがクリックボタンの動作をトリガーすると、処理対象メッセージがqueueに入り、関連する関数はhandleClick
である.全体運転プロセス
全体の実行手順は以下の通りです(図のように).
上記プロセスループが実行されるので、イベントループ(Event Loop)と呼ぶ
//
var req = new XMLHttpRequest();
req.open('GET', url);
req.onload = function (){}; // , , api,
req.send();
*タスクキューのタイプ
補足説明:タスクキューは2つのクラスに分けられます.
3.タイマー
上記Event Loopモデルでは、メッセージキューの新しいメッセージソースは、domイベントアクション、ajaxリクエストなどの他に、タイミングタスク、すなわち
setTimeout
によって作成されたタスクであってもよい.この関数はよく知られているに違いないが、必ずしもよく知っているとは限らないかもしれない.setTimeout
は2つのパラメータを受け入れます.// 1
console.log(1);
setTimeout(function(){console.log(2);},1000);
console.log(3);
// 1 3 2 , setTimeout 1000
この例はsettimeoutの基本的な役割を説明しており,比較的簡単ではない.
// 2
const s = new Date().getSeconds(); //
setTimeout(function() {
// "2", 500
console.log("Ran after " + (new Date().getSeconds() - s) + " seconds");
}, 500);
while(true) {// , 2s,
if(new Date().getSeconds() - s >= 2) {
console.log("Good, looped for 2 seconds");
break;
}
}
//
Good, looped for 2 seconds
eventloop.html:15 Ran after 2 seconds
この例では、まず、
setTimeout
を使用して500ミリ秒後に実行されるコールバック関数を指定し、その後、while
サイクルを使用して、現在の実行を2秒以上意図的に実行する.実際には500ミリ秒目にメッセージキューにこのメッセージが追加されましたが、現在のプライマリ・スレッドが実行されていないため、呼び出しスタックが空になっていないため、500ミリ秒で
setTimeout
で指定されたコールバック関数は実行されません.実際には、上記のコードの500
を0
に変更しても、結果は同じです.簡単に言えば、
setTimeout(fn,x )
のxは、fnが実行される最小待ち時間を指定するだけであり、既存の呼び出しスタック関数の実行の進捗状況、およびメッセージキュー内の前のタスクの実行の進捗状況に応じて、具体的にどのくらいの時間後に実行できるかを示す.小結
この論文では、JS非同期トピックの基礎編であるEvent Loopモデルプロセスおよび一般的なタスクキューのいくつかのタスクキューメッセージソースについて説明します.
参考文献:MDN-EventLoopJavaScript実行メカニズム詳細:Event Loopについて
慣例:内容に間違いがある場合は指摘を歓迎します(理解できないと感じてツッコミを入れても全然大丈夫です);もし助けがあれば、称賛とコレクションを歓迎して、転載して同意を得てから出典を明らかにしてください、もし問題があれば私信の交流を歓迎して、ホームページはメールアドレスがあります