Call Stack, Task Queue, Event Loop

JavaScript 언어를 공부하던 중 비동기 처리 방식을 이해하기 위해서는 Call Stack, Task Queue, Event Loop의 개념을 알아야 한다는 것에서부터 흥미를 느껴 공부한 내용을 기록해보려고 한다.
작성 순서
1. Call Stack, Task Queue, Event Loop 란?
2. Call Stack, Task Queue, Event Loop 이해하기 위한 나만의 설명 + 사진
그럼 이제 자바스크립트에서 함수를 호출할 때 보이지 않는 곳에서 무슨 일이 일어나는지에 대해서 살펴보자.
1. Call Stack, Task Queue, Event Loop 란?
콜 스택(Call Stack)
모든 프로그래밍 언어에는 보이지 않는 곳에서 함수를 호출을 관리하는 데이터 구조가 있다. (JavaScript의 경우에는 Call Stack)
콜 스택 (Call Stack)
- 함수 호출을 관리하는 데이터 구조
- 데이터 구조: 스택(stack) - LIFO(Last In First Out)
- 마치 책상 위에 쌓여 있는 종이 더미처럼, 우리가 새로 추가하는 함수가 제일 꼭대기에 위치하게 된다.
- 자바스크립트가 return 키워드를 확인하거나, 함수 안에 더이상 실행할 코드가 없으면 컴파일러가 스택의 제일 위에 있는 항목을 제거할 것이다.
테스크 큐(Task Queue)
태스크 큐(Task Queue)는 비동기 함수의 콜백함수 또는 이벤트 핸들러가 일시적으로 보관되는 영역이다.
태스크는 비동기 함수를 실행시켰을 때 콜스택에 바로 push 되지 않고 Web API(Window, Document, Event, XMLHttpRequest, Fetch 등)와 같은 백그라운드로 작업을 넘겨준다.
이벤트 루프(Event Loop)
이벤트 루프(event loop) 정의는 아주 간단하다.
이벤트 루프는 태스크가 들어오길 기다렸다가 태스크가 들어오면 이를 처리하고, 처리할 태스크가 없는 경우엔 잠드는, 끊임없이 돌아가는 자바스크립트 내 루프입니다.
콜스택(Call Stack)에서 이벤트가 순차적으로 진행되면 이어서 콜백큐(Callback Queue)에서 하나씩 동작을 Loop 시키는 것을 말합니다.
2. Call Stack, Task Queue, Event Loop 이해하기 위한 나만의 설명 + 사진

위 이미지처럼 JavaScript는 기본적으로 실행한 코드들이 JavaScript의 Call Stack에 하나씩 쌓이는 구조를 가지고 있다.
JavaScript 프로그래밍 언어는 대표적으로 웹 브라우저에서 제공하는 여러가지 기능들 setTimeout, setInterval, addEventListerner의 콜백함수, then과 같은 메서드 처럼 JavaScript 자체에서 사용할 수 없는 기능들을 실제로 사용하기 위해서는 위에 보여지는 그림과 같이 Web API를 거쳐 Tast Queue로 이동해 Event Loop의 도움을 받아 그 내용을 실제로 실행할 수 있다.
이러한 개념들이 실제로 어떻게 동작하는지 알아보는게 이번 포스팅의 내용이다.
setTimeout(() => {
console.log(1)
}, 0)
console.log(2)
출력
2
1
위 코드를 보고 처음 JavaScript를 공부하는 사람은 setTimeout이 0ms 후에 콜백함수를 실해하니까 콘솔창에 1, 2 순으로 나오겠다고 생각할것이다.
위와 같은 결과가 왜 이렇게 나오는가에 대해 알고 있다면 여기까지 보면된다. (ㅋㅋㅋ_)
우리는? 나는? 아직 자세하게 모르기에 위 내용을 이해하려면 JS의 Call Stack과 Task Queue, Event Loop라는 개념에 대해 명확하게 이해를 하고 있어야 한다.
setTimeout(() => {
console.log(1)
}, 0)
console.log(2)
위 코드를 보면 첫 번째로 실행되는 코드는 setTimeout 함수이므로 JS Call Stack에 담기게 된다.
하지만 setTimeout 함수는 JS 자체에서 지원하는 기능이 아니고 브라우저에서 지원하는 기능이므로 Web APIS에 해당해 콜 스택에서 바로 실행될수는 없다.
그렇기에 setTimeout 함수는 Web APIS의 도움을 받아 Task Queue로 넘어가게 된다.
Task Queue로 이동된 setTimeout 함수는 결과적으로 콜백함수를 몇 초 뒤에 실행할 것지를 지정하는 함수이기 때문에 이 콜백의 내용이 Task Queue로 넘어가게 된다.
위 내용을 바탕으로 정리를 해보면 아래와 같은 모습으로 볼 수 있다.

정리
코드 상에서 setTimeout 함수가 실행이되면 JS의 기능으로는 실행할 수 없기에 Web APIs에서 0초를 기다린 후 Callback Queue에다가 쌓을수 있다. (박스 형태로 쌓여져 있는 콜백의 내용이 Queue라는 개념임)
이렇게 한 사이클이 돌게되면 setTimeout은 실행이되어 없어지게 되고 밑에있는 console.log를 통해 다음 stack이 만들어지게 된다.
console.log는 JS상에서 바로 실행할 수 있기 때문에 별도의 Web API 도움을 받지 않더라도 바로 실행가능하다.
사진으로 봐보자

그러면 아래와 같이 JS Call Stack에 더 이상 쌓을 내용이 없어서 내용이 비워지면 그때 Event Loop라는 개념을 통해 Task Queue에 존재하는 함수를 이제 JS Call Stack으로 넣어줄 수 있다.

그러면 Task Queue에 있는 콜백 함수 ()=> {} 가 JS Call Stack으로 이동하고 이 콜백 함수 내부에 있는 console.log(1)이 다음 Stack으로 쌓일 수 있다.

그럼 기존의 Task Queue에 있는 내용은 없어지게 되고 Call Stack에 쌓인 내용이 실행될텐데 LIFO(Last In, First Out)라는 개념으로 콜스택이 동작하게 된다. (LIFO - 후입 선출)
그렇기에 나중에 들어온 console.log(1)이 실행되 콘솔창에는 2 다음으로 1이 출력이되고 마지막에 콜백함수가 소비가 되면서 최종적으로 JS Call Stack과 Tast Queue가 전부 다 비워지게 되고 브라우저에서는 아무런 동작을 하지 않게 된다.

조금 더 쉽게 이해해보자면 JavaScript라는 프로그래밍 언어에서 직접적으로 동작할 수 있는 코드는 콜스택에 쌓여서 바로바로 실행될 수 있지만 대표적으로 setTimeout과 같은 함수는 JS 내부에서 지원하는 내용이 아니기 때문에 브라우저에서 제공하는 Web API의 도움을 받아 실행할 수 있고 그렇게 실행될 때 들어가는 콜백 함수는 Web API를 통해 바로 Call Stack으로 가는게 아니라 Task Queue에 쌓이는 구조를 가지게된다.
이렇게 Task Queue에 쌓이는 콜백 함수는 Call Stack이 완전히 비워져야지만 Event Loop를 통해서 하나씩 들어갈 수 있고 그렇게 JS Call Stack에 쌓인 내용들이 LIFO를 통해 모두 소비 되어야만 끝이난다.
+)
지금까지 설명으로 이해가 됐다면 아래 코드를 보고 정답을 유추해보자
function a() {
console.log('A')
function b() {
console.log('B')
}
}
function c() {
console.log('C')
}
function first() {
a()
c()
}
function second() {
c()
}
first()
second()
-------------------------------------------------------------------
결과
A - first() => a() => console.log('A') 순으로 콜스택에 스택이 쌓이고 바로 소비할 수 있는 코드를 만나게 되면 바로 실행하고 콜스택에서 없어짐
B
- first() => a() => b() => console.log('B') 바로 소비가능 실행후 사라짐
- 함수 내부 코드들을 전부 사용했기에 동작을 더이상 할 수 없어서 first()만 남기고 전부 사라짐
C
- first() => c() => console.log('C')
- 내부 동작 코드 없으므로 전부 사라짐
C
- second() => c() => console.log('C')
- 내부 동작 코드 없으므로 전부 사라짐
결론
이렇게 나만의 언어와 HTML, CSS, JS로 화면에 출력한 사진을 가지고 이해해봤는데, 면접 때 이에 관련되어서 질문이 나오면 어떻게 답을 해야할까?
화이트보드가 있다면 그림을 그려가며 설명하면 좋을텐데.... 따로 정리를 해야할 것 같다.
프론트엔드 공부일지 입니다.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!