JavaScriptのスレッド(#イベントループ)


「仲介プロセス」とは?
プロセスは実行中のプログラムと言える.すなわち、ユーザが作成したプログラムは、オペレーティングシステムによって메모리 공간을 할당받아 실행 중인 것を生成する.これらのプロセスは、プログラムに使用される데이터およびメモリなどの자원および스레드から構成される.
デジタルスレッドとは?
スレッド(thread)とは、プロセス内で実際に動作を実行する주체を指す.各プロセスには、操作を実行するために1つ以上のスレッドがあります.また、2つ以上のスレッドを有するプロセスをマルチスレッドプロセス(マルチスレッドプロセス)と呼ぶ.
JavaScriptの最大の特徴の1つは、同期言語である単一スレッドベースの言語です.単一スレッドであれば,一度に1つのタスクしか実行できないと考えられる.では、JavaScriptを主に使用するサイトは、どのようにして複数のリクエストを同時に受け取るのでしょうか.

1.概要


(1)JavaScriptは本当にシングルスレッドですか?


そうだ.正確には、javascriptのプライマリスレッド이벤트 루프は単一スレッドであるため、javascriptを単一スレッド言語と呼ぶ.ただし、イベントループは独立して実行されるのではなく、WebブラウザやNodeJSなどのマルチスレッド環境で実行されます.
すなわち、javascript自体は単一スレッドであるが、javascript実行時は単一スレッドではない.

(2)JavaScriptがシングルスレッドなら…

console.log("1");
setTimeout(console.log, 5000, "2"); // 5초 후, console.log 함수 실행
console.log("3");

// [출력]
// 1
// 3
// 2
どうして出力値が1.2.3ではないのですか?
setTimeout(...)5秒後にコンソールウィンドウに「2」を出力する必要があります.単線程ラーメン setTimeout(...) 関数が完了すると、次のコードを実行する必要がある場合があります.でも「3」は先に出力しました. (0ミリ秒の場合、結果は同じです.settimeoutには遅延があります)
📌 既存の同期要求
既存の同期要求は、コードを1行1行実行します.したがって、1つのタスクにどれだけ時間がかかるかにかかわらず、最初のコードが実行された後、次のコードが実行されます.이렇게 되면 앞의 작업시간이 길수록 시간 및 자원의 낭비가 심해진다.のリクエストの完了を待つ必要がなく、異歩で克服することができます.
では、JavaScriptは単一スレッドですが、複数のリクエストを同時に処理するにはどうすればいいのでしょうか.非同期操作で複数のリクエストを処理します.では、非同期操作はどのように動作しますか?
この現象を理解するためには,イベントループを理解する必要がある.

(3)イベントループと用語クリーンアップ


  • JSエンジン構成
  • JAvascriptエンジンはMemory HeapCall Stackから構成されています.最も有名なのはグーグルのV 8エンジンです.JAvascriptは、Call Stackが1つであることを意味する単一スレッドプログラミング言語です.
    エンジン(v 8)リクエストが送信されるたびに、リクエストを呼び出しスタックに順番に入れて処理するだけです.では、非同期リクエストはどのように実現され、誰が同時性を処理しますか?これがJavaScriptエンジンを駆動する環境、すなわちブラウザまたはノードです.jsが担当する.(もう一度言うとjavascriptエンジンは単一スレッドで、それを駆動する環境はブラウザエンジンとNode.jsです.)
    ブラウザエンジン:ChromeなどのWebブラウザエンジンで、さまざまなタスクを実行
    呼び出しスタック(Call Stack):JavaScriptは実行する関数を呼び出しスタックに順次入れて処理する
    Memory Heap:メモリ割当てが発生した場所(ex、宣言された変数、関数などを含む)
    Call Stack:コード実行時のスタック位置.山積みになる.
  • Web APIs
  • Web APIは、ブラウザが提供するAPIであり、DOMAjaxTimeoutなどがある.Call Stackで実行される非同期関数はWeb APIを呼び出し、Web APIはコールバック関数をCallback Queueに入れる.(promise, callback, clickevent etc..)
  • Callback Queue
  • 非同期で実行されるコールバック関数の領域を保存します.Task QueueMicrotask Queueなどがあります.(settimeout、promiseなど他のキューに追加)
  • Event loop
  • イベントループはCall StackとCallback Queueの状態をチェックし、Call Stackが空になったときにCallback Queueの最初のコールバックをCall Stackに追加します.

    2.イベントループと同時

    1 - (2)のコードがどのように処理されているかをゆっくり見てみましょう.

    line 1 : console.log("1") 実行コード



    1)コールスタック console.log("1") 追加
    2) console.log("1") 実行、コンソールウィンドウの「1」出力
    3)運転完了後、Call Stackにて console.log("1") 削除

    line 2 : setTimeout(console.log, 5000, "2") 実行コード



    1)コールスタック  setTimeout(...)  追加
    2) setTimeout(...) 実行、Web APIのtimer 스레드(前述のTimeOut)にタスクを渡す
    *つまり、timer 스레드サブスレッドで5秒待ちのタスクが実行される.したがって、プライマリ・スレッドは5秒以内にブロックされず、次のコードを実行できます.これは、JavaScriptが呼び出しスタックの単一スレッドであっても、複数のトランザクションを同時に処理するように動作できる理由です.これは. 同時性として表示されます.
    3)実行済み setTimeout(...)Call Stackから消えます.
    同期:複数のタスクが同時に発生しているように見えます

    line 3 : console.log("3") 実行コード



    1)コールスタック  console.log("3")  マウント
    2) console.log("3") 実行、コンソールウィンドウで「3」を出力
    3)運転完了  console.log("3")  Call Stackから削除

    5秒後、Web APIのtimerスレッド console.ログ(「2」)をCalback Queueに移動
    (厳密には、5秒後の待ち時間ではなく、5秒後の待ち時間です)

    1)イベントリングがCalback Queueにある console.Call Stackにlog(「2」)を追加
    イベントループ(Event Loop)は、常にループ内でCall StackとCallBack Queueをチェックします.Call Stackが空の場合は、Calback Queueの関数を1つずつCall Stackに上げます.
    2)スタック内の関数を呼び出し、コンソールウィンドウに「2」を出力する
    3)運転完了 console.log("2") Call Stackから削除
    JAvascriptは単一スレッドですが、イベントループ、Web API(ノードがC++API)、Callback Queueが存在するため、非同期コールバック操作が可能です.

    3.Calback Queueにも種類があります


    従来Callback Queueは非同期実行コールバック関数を保存する領域であり,Task Queue,MicroTask Queueなどが存在していた.これは、settimeout、promiseなどが他のキューに追加されることを意味します.
    処理手順については、次のコードを参照してください.
    console.log("script start");
    
    setTimeout(function() {
      console.log("setTimeout");
    }, 0);
    
    Promise.resolve().then(function() {
      console.log("promise1");
    }).then(function() {
      console.log("promise2");
    });
    
    console.log("script end");
    上記のコードを実行すると、次の結果画面が表示されます.
    script start
    script end
    promise1
    promise2
    setTimeout
    Promise、settimeoutの順に運行するのは、PromiseがMicrostaskだからです.Microstaskは、一般的なタスクよりも優先度の高いタスクと簡単に言えます.すなわち,タスクキューで処理されるタスクであっても,まずマイクロタスクが実行される.
    すなわち、Promiseのthen()コールバックは、Task QueueではなくMicroTask Queueに含まれる.
    ソース
    JavaScriptイベントループ
    なぜJavaScriptはSingle Threedなのでしょうか?
    JavaScriptは本当にシングルスレッドですか?
    テーマのコンセプト