ブラウザが JavaScript を事前に解析するかどうか、またどのように解析するかについての私の知識不足に根ざしている可能性のある、関連する 2 つの質問:
var ws = new WebSocket("ws://ws.my.url.com");
ws.onOpen = function() { ... };
コールバックでラップする以外に、の初期化を直接制御する方法はないようですWebSocket
が、JavaScript コードがロードされてコンストラクターに到達するとすぐに接続が作成されると思いますか?
プロパティはいつ にonOpen
アタッチされますかws
? 競合状態の可能性はありますか (何らかの理由でソケットの定義と の定義の間にコードがあった場合onOpen
)。onOpen
接続が確立される前/後に が決定不能にバインドされます (オプションで を確認できることは知っていますws.readyState
)。これに加えて、WebSocket ハンドシェイクはブロックされていますか?
現時点ではすべてドラフトであり、実装に依存している可能性があり、非常に明白な何かを見逃している可能性があることは理解していますが、インターネットで検索したり、ドラフトの W3C 仕様をざっと読んだりしても特に関連するものは見つかりませんでした。そのため、Websockets/JavaScript の内部動作を理解する上で役立つ情報があれば、非常にありがたいです。
ベストアンサー1
JavaScript はシングル スレッドであるため、現在の実行スコープが完了し、ネットワーク実行が実行される機会が得られるまで、ネットワーク接続を確立できません。実行スコープは、現在の関数 (connect
以下の例の関数) である可能性があります。そのため、setTimeout を使用して非常に遅い段階でバインドすると、イベントを見逃す可能性onopen
があります。たとえば、次の例では、イベントを見逃す可能性があります。
ビュー:http://jsbin.com/ulihup/edit#javascript,html,ライブ
コード:
var ws = null;
function connect() {
ws = new WebSocket('ws://ws.pusherapp.com:80/app/a42751cdeb5eb77a6889?client=js&version=1.10');
setTimeout(bindEvents, 1000);
setReadyState();
}
function bindEvents() {
ws.onopen = function() {
log('onopen called');
setReadyState();
};
}
function setReadyState() {
log('ws.readyState: ' + ws.readyState);
}
function log(msg) {
if(document.body) {
var text = document.createTextNode(msg);
document.body.appendChild(text);
}
}
connect();
例を実行すると、「onopen called」ログ行が出力されないことがわかります。これは、イベントを見逃したためです。
new WebSocket(...)
ただし、とイベントへのバインディングを同じ実行スコープ内に保持するとonopen
、イベントを見逃す可能性がなくなります。
これらがどのようにキューに入れられ、スケジュールされ、処理されるかについての詳細は、scope of execution
John Resigの投稿をご覧ください。JavaScript のタイマー。