web-dev-qa-db-ja.com

JavaScriptはバックグラウンドでAJAX応答をどのように処理しますか?

JavaScriptは単一のスレッドで実行されるため、AJAXリクエストが行われた後、バックグラウンドで実際に何が起こりますか?これについてより深い洞察を得たいと思います。

136
aziz punjani

カバーの下に、javascriptにはイベントキューがあります。 javascript実行スレッドが終了するたびに、キュー内に処理する別のイベントがあるかどうかを確認します。存在する場合、キューからそれを引き出し、そのイベントをトリガーします(たとえば、マウスクリックなど)。

Ajax呼び出しの下にあるネイティブコードネットワーキングは、ajax応答がいつ行われたかを認識し、イベントがjavascriptイベントキューに追加されます。ネイティブコードがajax呼び出しがいつ行われるかを知る方法は、実装に依存します。スレッドで実装することもできますし、イベント駆動型にすることもできます(実際には関係ありません)。実装のポイントは、ajax応答が完了すると、一部のネイティブコードがそれを認識し、JSキューにイベントを入れることです。

その時点でJavascriptが実行されていない場合、イベントはすぐにトリガーされ、ajax応答ハンドラーが実行されます。その時点で何かが実行されている場合、現在のJavaScriptスレッドの実行が終了すると、イベントが処理されます。 JavaScriptエンジンによるポーリングは必要ありません。 Javascriptの一部が実行を終了すると、JSエンジンはイベントキューをチェックして、実行する必要があるものがあるかどうかを確認します。その場合、キューから次のイベントをポップして実行します(そのイベントに対して登録されている1つ以上のコールバック関数を呼び出します)。イベントキューに何もない場合、JSインタープリターには、外部エージェントがイベントキューに別のものを入れて再び起動するまでの空き時間(ガベージコレクションまたはアイドル)があります。

外部イベントはすべてイベントキューを通過し、javascriptが実際に別の何かを実行している間はイベントがトリガーされないため、シングルスレッドのままです。

詳細については次の記事をご覧ください。

208
jfriend00

here は、javascriptでのイベント処理に関する非常に完全なドキュメントです。
これは、Opera Browser。

より正確には、「イベントフロー」、「イベントキューイング」および「非ユーザーイベント」というタイトルを見てください。

  1. Javascriptは、ブラウザのタブまたはウィンドウごとに1つのスレッドで実行されます。
  2. イベントはキューに入れられ、順番に実行されます。
  3. XMLHttpRequestは実装によって実行され、コールバックはイベントキューを使用して実行されます。

注:元のリンクは link でしたが、現在は無効です。

16
qwertzguy

回答で言及したajaxの実装に関して、少し詳しく説明したいと思います。

(通常の)Javascriptの実行はnotマルチスレッドですが-上記の回答でよく指摘されているように-howeverAJAX responsesの実際の処理(および要求処理)はnotJavascriptです。 -通常-isマルチスレッド。 (上記で説明するXMLHttpRequestの chromium source implementation を参照)

説明します。次のコードを見てみましょう。

var xhr = new XMLHttpRequest();

var t = Date.now;
xhr.open( "GET", "https://swx.cdn.skype.com/shared/v/1.2.15/SkypeBootstrap.min.js?v="+t(), true );

xhr.onload = function( e ) {
                console.log(t() + ': step 3');
    
    alert(this.response.substr(0,20));
};
console.log(t() + ': step 1');
xhr.send();
console.log(t() + ': step 2');

after an AJAX request is made(ステップ1の後)、jsコードの実行中(ステップ2以降)に、ブラウザーは次の実際の作業を開始します。1. tcp要求のフォーマット2.ソケットを開く3.ヘッダーの送信4 。ハンドシェーク5.ボディの送信6.応答の待機7.ヘッダーの読み取り8.ボディの読み取りなどこの実装はすべて、通常、jsコードの実行と並行して別のスレッドで実行されます。たとえば、言及されているクロム実装は ThreadableLoader go digg-into ????、(また、ページの読み込みの[ネットワーク]タブを確認すると、いくつかの同時リクエストが表示されます)。

結論として、少なくとも-あなたのI/O操作の大部分は同時に行うことができます(そしてawaitなどを使用してこれを利用できます)。ただし、これらの操作(発行、jsコールバックの実行)とのすべての対話はすべて同期です。

0