Call Stack, Non-Blocking IO, Event Loop


ノードをよりよく理解するためには、まずJavaScriptの同期モデルを理解する必要があります.
JavaScriptの実行モデルは,イベントループ,Call Stack,Callback Queueの概念からなる.

Event Loop


イベントループモデルでは、複数のスレッドが使用されます.
ここで我々が作成したJavaScriptコードで実行されるスレッドは、プライマリスレッド、ノードと呼ばれています.jsプロセスでは、プライマリ・スレッドは1つであり、一瞬にして1行しか実行されません.
ただし、他の作業(e.g.File I/O,network)の作業スレッドがある場合があります.

Call Stack


現在呼び出されている関数のスタック

function f3() {};
function f2() {};
function f1() {};
f1();

// f1() 쌓임 > f2() 쌓임 > f3() 쌓임 
// f3() 빠짐 > f2() 빠짐 > f1() 빠짐

Run-to-completion


では、Call StackはJavaScript実行モデルとどのような関連がありますか?
Call Stackがアイドル状態から始まり、特定の要因によりコールバック(利息関数)が実行されると、
スタックが連鎖した関数で積み上げられ、すべて脱落すると、空き状態に戻ります.
Event Loopが次のコールバックを処理するには、現在処理中のコールバックが完全に完了する必要があります.
👉 これは、コールスタックが完全に空になるまで処理することを意味します.

Call Back Queue (= Message Queue)


名前の通り、CallBackが積み上げたQueue


Call Back Queueは、後で実行するコールバック(関数およびそのパラメータ)を積み重ねたQueueです.
コールバックは、ブラウザまたはノードで特定のイベントが発生したときにプライマリ・スレッドに通知するために使用されます.
イベントの例としては、ファイル処理の完了、ネットワーク操作の完了、タイマ呼び出しなどが挙げられる.
setInterval(() => {
	console.log('잘가!');
  	while(true) {}
}, 1000)
Q.上記のコードを5秒以内に実行した場合、何回情報を出力しますか?
A.1号>whileサイクルの間、Call Stackは絶対に空にされないからです.
JavaScript実行モデルでは、瞬時に実行されるコードは1つしかなく、呼び出しスタックが空になるまで次のコールバックは実行されません.
この間CallBack Queueからコールバックを取り出すことができないため、setIntervalがどのようにコールバックを蓄積してもプライマリスレッドでは実行できません.
JavaScriptのプライマリ・スレッド上で同期処理が必要な煩雑なタスクを実行すると、これらのタスクを処理するとCallback Queueは他のコールバックを実行できません.
👉 ノードの非同期性を最大限に高めることはできないため、このようなイベントのブロックを回避する必要があります.

Non-Blocking I/O & Offloading

// Node에게 파일 읽기를 요청 후
// 워커 스레드에서 파일을 읽기 시작

fs.readFile(fileName, (err,data) => {
  	// Node가 파일을 모두 읽으면
  	// 1. 콜백큐의 이 함수에 err, data 인자를 채우고
  	// 2. 콜백큐에서 꺼내질 때 이 부분이 실행 됨
});

// readFile의 호출이 끝난 직후 바로 이 함수를 실행
// 이는 여전히 같은 콜백을 처리하는 중이기 때문
someTask();
ブラウザまたはノード.jsにおいても、Web APIまたはNode APIの操作が完了すると、callbackキューに登録されます.
ブラウザまたはノードが要求された作業を実行している場合、プライマリ・スレッドとイベント・ループは影響を受けずに実行されます.
👉 これはOffloadと呼ばれます.これは、ノードサーバがプライマリ・スレッドが1つしかないにもかかわらず、迅速に実行できる理由です.