1

私は以下のようなコードを持っています:

var ws = new WebSocket("ws://localhost");
ws.onopen = function() {
    // Long running loop
    for (var i = 0; i < 1000000; i++) {
        ws.send(i);
        console.log(i);
    }
};

ループが完了した後、サーバーはメッセージを受信するだけです(または、クライアントがメッセージの送信を開始するだけだと思います)。これはなぜですか?

4

2 に答える 2

2

ページを使用した実行のいくつかの領域は次のとおりです。

  • JavaScript
  • DOM レンダリング
  • 通信網

私はこれをしばらくテストしていませんが、関数を実行する (または 1 つのスコープでコードを実行する) 場合、DOM を更新するための呼び出しを行うか、ネットワーク要求を行う場合は、まだそうであると想定しています。現在のスコープが存在するまで発生しません。

例えば

function doSomething() {
  document.body.innerHTML += 'hello';
  var ws = new WebSocket('ws://my-websocket-endpoint.com');
  ws.onopen = function() { alert( 'awesome!' ); };
}

doSomething();

上記のコードでは、次のことが起こります。

  • doSomethingが実行され、内部コードが実行されます。
  • doSomething返品とスコープの変更
  • ブラウザーが UI スレッドに保留中の更新を実行する機会を与えると、DOM に「hello」が表示されます。
  • WebSocket 接続が行われます
  • alert火が通るまで、まだしばらくかかりそうです。

例を具体的に見てみWebSocketましょう。インスタンスを作成した後にイベント ハンドラーを追加できるという事実を考えると、WebSocketこれは、コンストラクターを呼び出すとすぐに接続が発生しないことを意味します。接続は、現在の実行範囲が完了したときにのみ試行されます。これを 100% 確認することはできませんがWebSocket.send、実行のスコープが完了するまで関数が実際にデータを送信する可能性は非常に低いです。

var ws = new WebSocket('ws://my-websocket-endpoint.com');

function sendStuff() {
  for( var i = 0; i < 10000; ++i ) {
    ws.send( i );
  }
}

// Assume we are connected
sendStuff();

上記のコードでは、次のことが期待されます。

  • sendStuff呼び出されるには、ループを実行して終了します
  • ブラウザーは、ネットワーク アクティビティを含め、保留中の他のすべてのものを処理します。これには、実際にデータを送信することも含まれます
于 2012-10-27T11:37:35.433 に答える
1

あなたの質問には答えませんが、コードが正しくないように見えることに注意してください。

あなたのnew WebSocket呼び出しは、サーバーとの非同期ハンドシェイクを開始します。これが完了するとonopen、websocket に登録したコールバックが実行されます。ws.send呼び出して、サーバーがメッセージを受信することを期待できるのは、この時点だけです。

次に、例を次のように作り直すことができます

var ws = new WebSocket("ws://localhost");
ws.onopen = function() {
    for (var i = 0; i < 1000000; i++) {
        ws.send(i);
        console.log(i);
    }
};
于 2012-10-27T17:49:39.317 に答える