web-dev-qa-db-ja.com

イベントループ、コールバックキュー、およびJavascriptのシングルスレッドはどのように接続されていますか?

一般的な目標

次のJavaScript環境がシステムとしてどのように相互接続するかを知りたいのですが。

  • Javascriptエンジン
  • イベントループ
  • イベントキュー

ノードは別の記事で取り上げられているため、これをブラウザ環境に制限できます( ここ

私が(信じる)理解すること:

  • Javascriptはシングルスレッドであるため、コールスタックは1つだけです。

  • Javascript環境は、真に非同期であるいくつかの関数のみを提供します。これらには、setTimeout()、setInterval()、およびI/O関数が含まれる場合があります。

  • 開発者は、これらのいずれかを使用せずに独自の非同期関数を作成することはできません。
  • Javascript自体は同期的に実行されますが、現在のコールスタックがクリアされると、非同期関数を介してブロッキング関数をコールバックできます。

例:

      console.log(‘Sync code started…’);

      setTimeout(function asyncLog() {
           console.log(‘Async function has completed’)
      }, 2000);

      console.log(‘Sync code finished…')

手順の例:

(間違っている場合は手順を修正してください)

  1. 「同期コードが開始されました…」がログに記録されます
  2. setTimeoutがスタックに追加されますが、すぐに制御を返します
  3. setTimeoutは別の「スレッド」…「ワーカー」に送信されますか? 2000ミリ秒をカウントするためのjavascriptの単一スレッドの外側
  4. 「同期コードが終了しました…」がログに記録されます
  5. 2000ミリ秒後、asyncLog()がイベントキューにプッシュされます
  6. コールスタックがクリアであるため、イベントループは保留中のコールバックについてイベントキューをチェックします
  7. asyncLog()はキューから削除され、イベントループによってスタックにプッシュされます
  8. 「非同期機能が完了しました」がログに記録されます
  9. コールスタックがクリアになりました

質問

非同期関数(setTimeoutなど)が最初にコールスタックにヒットしてからコールスタックにコールバックされるまでの手順の概要を誰かが作成できれば、これらに1つずつ答える必要はありません。

  1. ステップ3で、誰がこの新しいスレッドを作成しますか?それはブラウザですか?
    • この新しいスレッドは正しくブロックされていますか?
    • 1000のsetTimeoutsを作成するループがある場合はどうなりますか。 1000個の「スレッド」が作成されていますか?
    • 一度にスポーンできるスレッドの数に制限はありますか?
    • 新しいスレッドの実行が終了すると、どのようにしてキューに入れられますか?
  2. 誰がイベントキューを提供しますか?
  3. イベントループを提供するのは誰ですか?
    • イベントループはイベントキューをポーリングしますか?
    • Javascriptのスレッドはイベントループを認識していますか?それとも、イベントループは物事をスタックにプッシュするだけですか?
    • スタックがクリアされたことをイベントループはどのように知るのですか?
21
kurtcorbett

あなたの理解とあなたの例は基本的に正しいようです。さて、あなたの質問に:

ステップ3で、誰がこの新しいスレッドを作成しますか?それはブラウザですか?

はい。これは基本的に、これらの「真の非同期」関数の実装を提供するものです。 IIRC、setTimeoutはJSエンジンに直接実装され、ネットワーキングIOは間違いなくブラウザの責任ですが、誰が作成するかは問題ではありません。あなたの「ブラウザ環境」は常にブラウザの一部です。

この新しいスレッドは正しくブロックされていますか?

はい。いいえ。実行する必要のある作業、つまり、呼び出した非同期関数によって異なります。新しいスレッドのスピンが必要なものもありますが、単純なタイムアウトの場合は、ノンブロッキングシステムコールが使用されていると確信しています。

1000のsetTimeoutsを作成するループがある場合はどうなりますか。 1000個の「スレッド」が作成されていますか?

可能。しかし、ありそうもない。本当に独自のスレッドを必要とする非同期アクションでは、スレッドプールが使用され、リクエストがキューに入れられると思います。このプールのサイズは、ブラウザーの構成の内部に隠れている可能性があります。

一度にスポーンできるスレッドの数に制限はありますか?

それはOSによって制御されます。

新しいスレッドの実行が終了すると、どのようにしてキューに入れられますか?誰がイベントキューを提供しますか?

基本的に、このような各スレッドの最後のアクションは、その結果をイベントキューに入れることです。

イベントループを提供するのは誰ですか?イベントループはイベントキューをポーリングしますか?

ループがキューをポーリングするか、キューがループの反復を駆動するかにかかわらず、これは実装の詳細だと思います。

Javascriptのスレッドはイベントループを認識していますか?それとも、イベントループは物事をスタックにプッシュするだけですか?

Javascriptはinイベントループスレッドを実行すると思います。イベントループは、キューからイベントを繰り返しポップし、JavaScriptを実行します。

スタックがクリアされたことをイベントループはどのように知るのですか?

イベントループcalls javascriptの実行-したがって、javascriptが戻ったときにスタックはクリアされます。

11
Bergi