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
setTimeout
1 秒間何かを実行しても、 1 秒後には実行されない可能性があることを理解することが重要です。スレッドがビジー状態の場合、実行されない可能性があります。
したがって、WebSocket 接続を開始して上記のようなループを実行しても、接続の準備が整うのを待っていると、ループが終了しない可能性があります。
JS に慣れていないプログラマーにとって、この動作は奇妙に見えるかもしれません。したがって、読みやすくするために、可能な限りコールバックを必要とする関数と同時に、または直後にコールバックを定義します。
スレッドと同時実行を明示的に使用する場合は、Web ワーカーの詳細をお読みください。
参照: