ブラウザ端Event loop概要

2060 ワード

javascriptを知ったことがありますが、その最大の特徴はシングルスレッドです.つまり同じ時間に一つのことしかできません.なぜマルチスレッドではいけないですか?理由はとても簡単で、マルチスレッドは複雑すぎて、仮にjavascriptに2つのスレッドがあったら、一つはdomを添加して、一つはdomを削除して、それではブラウザがぼんやりしていて、これは結局私がどれを選ぶべきですか?だから、不必要なトラブルを避けるために、javascriptは最初からシングルスレッドを選択しました.しかし、スレッドにも問題があります.サーバーにファイルを要求するという任務があると、このファイルが大きいと、すぐに次のステートメント(ファイルが戻ってくるまで待つ)を実行できなくなります.だからhttml 5はウェブワーカーの標準を提出して、javascriptが子スレッドを作成することを許可しますが、規定が厳格で、子スレッドはメインラインのプロセスによって制御され、domを操作できません.このような折衷方法はjavascriptをより柔軟にします.
これまでjavascriptは子スレッドを持つことができました.この時、前に述べたように、ioの操作に時間がかかります.このタスクを保留して、結果を返してから実行します.したがって、すべてのタスクは、同期タスク(上から次へステップ)、もう一つは非同期タスク(結果が出たら実行する、いわゆるメッセージキュー)の2つになります.この2つのタスクはスレッドに入るのとは違って、同期して上から下へと直接メインスレッド形成実行スタックに入ります.非同期のなど、戻りの結果があります.たとえば、ajax要求が成功したら、成功した回数をサブスレッドに戻します.現在、ブラウザはメインスレッドの中の実行スタックを実行し始めました.メインスレッドの中の実行スタックが全部終わったら、メインスレッドはサブスレッドの中を見に行きます.その前にタスクにどのようなフィードバックがあったかを確認します.もしリマインドがあったら、メインスレッドの中にその内容を入れて実行します.実行が終わったら、再度サブスレッドに行って、新しいリマインドがあるかを確認します.(ここで注意したいのは、メインスレッドが全部実行された後、サブスレッドを見に行くことです.)メインスレッドはこのステップを繰り返します.これはいわゆるEvent loopです.つまり、javascriptの運行メカニズムです.特殊なのはsetTimeout、setintervalの2つの方法です.これらもサブスレッドの中に入れられます.例えば、setTimeout(fn 3000)3 s後にfnというイベントを実行するとは限らず、メインスレッド内のタスクが完了するかどうかを確認します.
ケース1:
function f() {
  console.log("foo");
  setTimeout(g, 0);
  console.log("baz");
  h();
}

function g() {
  console.log("bar");
}

function h() {
  console.log("blix");
}

f();
      :foo 、baz 、 blix 、bar
ケース2:
var req = new XMLHttpRequest();
req.open('GET', url);    
req.onload = function (){};    
req.onerror = function (){};    
req.send();
var req = new XMLHttpRequest();
req.open('GET', url);
req.send();
req.onload = function (){};    
req.onerror = function (){};   
この2つの実行結果は同じです.まずOloadイベントを実行します.javascriptはメインコースが空いてから、サブスレッドのリプライ内容を確認します.
注意点:
非同期のタスクの実行順序は固定されていません.主に戻りの速度を見ます.aタスクはbタスクの前に書かれていますが、aタスクは長いです.bタスクは短い時間がかかります.bタスクはサブスレッドの中に戻ります.これはメインスレッドから先にポーリングされますが、bタスクネットワークが良くない場合もあります.aタスクは先に戻ります.フィードバックは先にサブスレッドに登録されています.これにより、aが先に実行されました.