ホームページ  >  記事  >  ウェブフロントエンド  >  JSのシングルスレッドとイベントループについて詳しく解説

JSのシングルスレッドとイベントループについて詳しく解説

小云云
小云云オリジナル
2018-03-31 17:16:373514ブラウズ

Js はシングルスレッドであり、js コードは上から下に順番に実行されます。たとえば、2 つの関数を作成した場合、上の関数が最初に実行され、下の関数が後で実行されます。しかし、この種の単一スレッドには非常に大きな問題があります。つまり、時間のかかるタスクが発生した場合、後続のタスクはそれが完了した後でしか実行できないということです。たとえば、ajax リクエストはサーバーからデータを取得しますが、ネットワークが遅い場合は、結果が返されるまでさらに時間がかかります。待機中のプロセスでは、ユーザーは何をすることもできません。また、レンダリング段階では、ユーザーは UI を表示することしかできません。空白のページがあり、エクスペリエンスが低すぎます。

このような時間のかかるタスクをどうするか、js はそれを脇に置いて、最初に後続のタスクを実行し、その後、これらの時間のかかるタスクを処理するために戻ってくることにしました。コードを記述する順序とコードが実行される順序が一致しないため、これにより非同期の概念が導入されます。以下に 3 つの関数、2 つの基本関数、および ajax 関数 (非同期操作用) がありますが、実行順序は add -> ajax です。

function add(num1,num2) {    return num1 + num2;
}function subtract(num1,num2) {    return num2 - num1
}function ajax() {    var url = 'http://jsonplaceholder.typicode.com/posts/1';    var xhr = new XMLHttpRequest();
    xhr.open("GET",url); 
    xhr.onload= function () {
        console.log(xhr.responseText)
    }
    xhr.send()
}ajax();

console.log(add(3,5))
console.log(subtract(3,5))
これにより、非同期タスクはどこに配置されるのかという別の質問が生じます。いつ実行されますか?実際、ここで注意すべき問題は、実際に ajax 操作を実行するのは js ではなく、ブラウザによって発行される http リクエストです。 js が ajax 関数を実行すると、実際にはブラウザに http リクエストを実行するように指示し、すぐに戻ってその背後にあるコード (加算関数と減算関数) を実行します。では、ブラウザが http リクエストを実行してサーバーからデータを取得した後は何をすべきでしょうか?次に、コールバック関数 (onload 関数) を実行します。これにより、返されたデータがコールバック関数に渡され、コールバック関数がイベント (タスク) キューに挿入されます。 js が加算関数と減算関数の実行を終了すると、何もする必要はありません。ポーリングするとすぐに、onload コールバック関数があることがわかり、それを取得します。この関数を実行してください。プログラムの実行中、js はプログラムが終了するまでポーリングを実行し続けます。

JSコードはプログラム全体の実行プロセス中に2つの部分に分割され、1つはadd関数のようなもの、もう1つはajaxのonloadコールバック関数のようなものです。これに対応して、jsの操作も2つの部分に分割され、1つは1 つはメインスレッド、もう 1 つはタスク (非同期コールバック関数) キューです。

jsコードの具体的な動作は以下の通りです:

1. jsコードがロードされるとすぐに上から下へ順番に実行され、非同期に遭遇するとグローバル実行環境にも入ります。 ajax 操作では、ブラウザーはリクエストを実行し、すぐに戻ります。add 関数の呼び出しに遭遇すると、ブラウザーは関数の実行環境に入ります。add 関数を実行した後、再度、subtract 関数に遭遇します。そして再び関数実行環境に入ります。もちろん、ここではより単純であり、入れ子になった関数はありません。関数内にネストされた関数がある場合、下図に示すようにサブ関数の実行環境に入り、上の関数が実行された後、下の関数が実行されるまで実行されます。グローバル実行環境のコード 実行が完了すると、実行スタックは空になります。これは、js のメインスレッドです。

2. ブラウザは今後、サーバーからデータを取得するか、失敗するかをタスクに登録します(コールバック関数)。 ) キューインスタンス内。

3. 実行スタック内のすべてのコードが実行されると、つまり実行スタックが空になると、js はタスク キューをポーリングします (タスクがある場合は、左の図)。タスクキューから取得 開始位置から最初のタスク(登録されたコールバック関数)を取り出し、実行スタックに置きます(右図) コールバック関数が実行されると、実行スタックは再び空になります。 js はタスク キューをポーリングし、コールバック関数がある場合は、最初の関数を取り出して実行のために実行スタックに置きます。プログラム全体の実行中、js はタスク キューをポーリングし続けます。タスクが存在すると、それが実行されます。これがイベント ループです。

すべてのプログラムはスタック上で実行され、実行スタックが空の場合にのみ、次のタスクを処理できます。関数が実行スタックに入る限り、スタックは空ではありません。スタックが空でない場合、次の関数は処理できず、関数が実行されるまで待つことしかできません。これは「実行から完了まで」と呼ばれ、一度に 1 つのことしか実行できません。これには、コールバック関数が多すぎるタスクを実行できないことも必要です。実行されるタスクが多すぎると、スタックが空にならず、次のタスクの実行が妨げられ、ブロックが発生します。

上記は js ではノンブロッキングです。

関連する推奨事項:

JavaScript の実行メカニズム JavaScript がシングルスレッドである理由

シングルスレッド JS とマルチスレッドブラウザの使用

ネイティブ JS の非同期とシングルスレッドの詳細な説明

以上がJSのシングルスレッドとイベントループについて詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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