Tech Blog of Pinomaker
Published 2022. 9. 1. 14:01
[JavaScript] Event Loop F.E/JavaScript

JavaScript에는 동시성 모델인 Event Loop, Call Stack, Callback Queue가 있다.

 

Event Loop

EventLoop는 여러개의 스레드를 사용하고, 그 중 우리가 작성한 JavaScript가 실행되는 스레드를 메인 스레드라한다.

이 메인 스레드는 Node JS 프로세스에서는 하나만 존재하며, 한 순간에 한 줄씩 실행된다.

하지만 그 이외의 일을 하는 워커 스레드는 여러개가 존재할 수 있다.

 

 

 

 

Call Stack

Call Stack이란 지금 시점까지 호출된 함수들의 Stack이다. 여기서 Stack은 자료 구조 중 하나며, 아래에서 위로 차곡 차곡 쌓이지만, 위에서부터 빼내는 자료 구조다. 

즉 함수가 호출 될 때 마다 하나 씩 쌓이고, 리턴 할 때 빠지게 된다.

이벤트 루프는 하나의 콜백이 끝나고 빈 상태가 되어야 다음 콜백을 처리할 수 있는 구조로, Call Stack이 완전히 빈 상태가 되어야 다음을 처리 할 수 있다.

 

 

Callback Queue

Callback Queue는 Callback들이 쌓이는 Queue다. 여기서 Queue는 자료 구조 중 하나이며, 처음 들어오는 것이 가장 먼저 나가는 자료구조이며, Callback Queue는 앞으로 실행할 Callback들을 쌓아두는 Queue다.

Queue란 자료구조는 처음 들어온 게 가장 먼저 나가는 자료 구조다.

콜백 큐는 앞으로 실행한 콜백들을 쌓아두는 큐다.

 

 

즉 JavaScript의 이벤트 루프는 CallStack들이 Callback Queue에 쌓이게 되며, Call Stack가 끝났을 때, 완전히 빈 상태가 되었을 때 다음 Call Stack을 꺼내서 실행하는 구조라고 생각하면 된다.

 

 

예시를 두가지를 통해 자세히 알아보자.

 

[예시 1번]

console.log(1)

setTimeout(() => {
  console.log(2)
}, 0)

console.log(3)

// 1, 3, 2

예시 1번을 의 출력 결과는 1, 2, 3이 아닌 1, 3, 2다 우리는 그 이유를 Call Stack과 Callback Queue를 통해서 알아볼 수 있다. 

console.log(1) -> setTimeout() -> console.log(3)의 순서로 Queue에 담겨서 실행하게 되고, console.log(2)는 setTimeout이 끝나야 Callback Queue에 담겨 실행하게 된다. 

따라서 console.log(1) -> setTimeout() -> console.log(3) -> console.log(2) 순으로 실행 된다.

 

[예시 2번]

 

setInterval(() => {
  console.log("Hello")
  while(true){}
}, 1000)

// Hello

예시 2번은 1초에 한 번씩 console.log와 while 문을 실행 시키는 코드이며, 결과는 Hello를 5번 실행 시키는 것이 아니라 단 한 번만 실행한다. 그 이유는 while loop가 true로 설정되어 탈출을 할 수 없기에 계속 while loop가 돌게 되고 이는 Call Stack이 절대 비지 않아서 Queue가 다음 콜백을 실행시키지 않는다. 이렇게 Event Loop가 막히는 것을 Bloack 한다고 말한다.

 

 

브라우저나 Node JS 등의 동작이 끝나면 Callback Queue에 등록을 하게 되고, 그들이 요청 받은 일을 하고 있는 동안은 메인 스레드와 이벤트 루프는 영향을 받지 않고 계속 실행하게 된다. 이를 offloading이라고 한다.

offloading은 Node JS의 서버가 메인 스레드가 하나임에도 빠르게 동작할 수 있는 이유로, 메인 스레드가 오래 걸리는 일을 기다리지 않기에 가능한 일이다.

profile

Tech Blog of Pinomaker

@pinomaker

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!