8

Websocketを開くために使用されるいくつかのコードを理解しようとしています:

var ws = new WebSocket('ws://my.domain.com');
ws.onopen = function(event) {
    ...
}

私の質問は、ハンドシェイクがどのように開始されるかです。WebSocketコンストラクターで開始された場合、それまでに設定されていない場合、onopenはどのように呼び出されますか? WebSocket コンストラクターがハンドシェークを行うスレッドを作成する場合、ハンドシェークが終了する前に onopen を十分に迅速に定義する必要がありますか? その場合、JS 仮想マシンの速度が低下すると、onopen が定義される前にハンドシェイクが終了する可能性があり、イベントが処理されないため、少し危険に思えます。または、 onopen 関数を設定するとハンドシェイクがトリガーされますか?

誰かが API の仕組みを説明してくれませんか?

4

2 に答える 2

10

onopen現在の (同期) コードの実行が終了するまで、関数は検索されません。これは、接続 (およびonopenコールバックの呼び出し) が非同期であるためです。検討:

let x = false;
setTimeout(function () {
    x = true
}, 1000);
while(!x){
    console.log('waiting!');
}

そこのwhileループは決して終了しませんが、おそらく 1 秒後に終了すると思われるでしょう。

onopen時間のかかる (ただし同期的な) コードを実行して関数の初期化を遅らせても、危険ではありません。一方、setTimeout初期化する場合onopen、どのコールバックが最初に実行されるかがわからないため、WebSockets 接続の準備が整った時点で定義されているかどうかは保証されません。

C++ で同じことを行う場合は、そのためにスレッドを使用します。JavaScript コールバック メカニズムでは、スレッドベースではありません。スレッドのように振る舞うだけです (上記の無限 while ループを参照してください)。

シングル スレッドは一度に 1 つのコード単位を実行し、現在のコード単位の実行が完了するまで、他のコード単位はキューに入れられます。

ソース: http://www.slideshare.net/clutchski/writing-asynchronous-javascript-101

setTimeout1 秒間何かを実行しても、 1 秒後には実行されない可能性があることを理解することが重要です。スレッドがビジー状態の場合、実行されない可能性があります。

したがって、WebSocket 接続を開始して上記のようなループを実行しても、接続の準備が整うのを待っていると、ループが終了しない可能性があります。

JS に慣れていないプログラマーにとって、この動作は奇妙に見えるかもしれません。したがって、読みやすくするために、可能な限りコールバックを必要とする関数と同時に、または直後にコールバックを定義します。

スレッドと同時実行を明示的に使用する場合は、Web ワーカーの詳細をお読みください。

参照:

于 2013-01-16T20:41:14.377 に答える