JavaScriptはシングルスレッドで実行されるため、AJAXリクエストが行われた後、バックグラウンドで実際に何が起こりますか?これについてより深い洞察を得たいのですが、誰かが光を当てることはできますか?
JavaScriptはシングルスレッドで実行されるため、AJAXリクエストが行われた後、バックグラウンドで実際に何が起こりますか?これについてより深い洞察を得たいのですが、誰かが光を当てることはできますか?
回答:
カバーの下に、JavaScriptにはイベントキューがあります。実行のJavaScriptスレッドが終了するたびに、処理するキューに別のイベントがあるかどうかを確認します。存在する場合は、キューからそれを引き出し、そのイベントをトリガーします(たとえば、マウスクリックなど)。
ajax呼び出しの下にあるネイティブコードネットワーキングは、ajax応答がいつ完了したかを認識し、イベントがjavascriptイベントキューに追加されます。ajax呼び出しがいつ行われるかをネイティブコードがどのように認識するかは、実装によって異なります。スレッドで実装することも、それ自体がイベントドリブンにすることもできます(これは重要ではありません)。実装のポイントは、ajax応答が完了すると、一部のネイティブコードがそれが完了したことを認識し、イベントをJSキューに入れることです。
その時点でJavaScriptが実行されていない場合、イベントはすぐにトリガーされ、ajax応答ハンドラーが実行されます。その時点で何かが実行されている場合、実行の現在のJavaScriptスレッドが終了すると、イベントが処理されます。JavaScriptエンジンによるポーリングは必要ありません。JavaScriptの一部が実行を終了すると、JSエンジンはイベントキューをチェックして、実行する必要があるものがあるかどうかを確認します。その場合、次のイベントをキューからポップして実行します(そのイベントに登録されている1つ以上のコールバック関数を呼び出します)。イベントキューに何もない場合、JSインタープリターには、外部エージェントが何かをイベントキューに入れて再びウェイクアップするまで、空き時間(ガベージコレクションまたはアイドル)があります。
すべての外部イベントはイベントキューを通過し、JavaScriptが実際に何かを実行している間はイベントがトリガーされないため、シングルスレッドのままです。
詳細は次のとおりです。
.focus()
アイテムを呼び出すと、フォーカスのあるアイテムに対する「ぼかし」イベントなど、他の2つのイベントがトリガーされます。このぼかしイベントは同期的に発生し、イベントキューを通過しないため、イベントキューにある他のイベントの直前に発生します。実際には、これが実用的な問題であるとは思いもしませんでした。
JavaScriptでのイベント処理に関する非常に完全なドキュメントをここで見つけることができます。
これは、OperaブラウザーでのJavaScriptの実装に取り組んでいる人によって書かれています。
より正確には、「イベントフロー」、「イベントキューイング」、および「非ユーザーイベント」というタイトルを見てください。次のことがわかります。
注:元のリンクだったリンクが、今死んでいます。
回答に記載されているajax実装について少し詳しく説明します。
(通常の)Javascriptの実行ではあるがない、マルチスレッド-上記の回答でも述べたように- しかし、の本当の取り扱いAJAX responses
(リクエストの処理だけでなく、など)がありません Javascriptを、そしてそれは-通常- であるマルチスレッド。(前述のXMLHttpRequestのクロムソース実装を参照してください)
説明します。次のコードを見てみましょう。
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コードの実行と並行して別のスレッドで実行されます。例として、言及されているchromiumの実装は、Threadable Loader go digg-intoを使用しています(ページのロードのネットワークタブを見ると、いくつかの同時リクエストが表示されます)。
結論として、私は-少なくとも-ほとんどのI / O操作を同時に/非同期に行うことができます(そして、たとえばawaitを使用してこれを利用できます)。ただし、これらの操作(発行、jsコールバックの実行)とのすべての対話はすべて同期です。