JavaScript의 여러가지 특징 중 가장 대표적인 3가지가 있다.
1. 비동기
2. 싱글스레드
3. 이벤트 루프
여기서 한가지 의문점이 든다.
"JavaScript는 싱글스레드이면서 비동기일 수가 있을까?"
이에 대한 답은 JavaScript 언어는 싱글스레드이고 비동기 행위들은 JavaScript 언어의 일부는 아니며, 비동기 행위는 프로그래밍 환경(브라우저 내부)에 존재하는 JavaScript 언어 코어(Core) 상위에 만들어져 있어 브라우저의 API를 통해 접근한다.
브라우저 내부 - 중요 컴포넌트
Heap 영역
- 객체는 대규모이면서 구조화 되지 않은 메모리 영역인 힙영역 내부에 할당된다.
Stack 영역
- JavaScript 코드 실행을 위해 제공된 싱글 스레드를 나타낸다.
Web API (브라우저)
- JavaScript 언어 코어(Core)의 상위에 만들어져, JavaScript 코드 사용할 떄 유용한 기능을 제공한다. 비동기 행위도 여기에 포함된다.
Event Queue 영역
- Event 핸들러, Timer 함수의 콜백 함수가 보관되는 영역으로 이벤트 루프(Event Loop)에 의해 특정시점(Call Stack이 비어졌을 때)에 순차적으로 Call Stack으로 이동되어 실행된다.
Event Loop
- Call Stack 내에서 현재 실행중인 task가 있는지 그리고 Event Queue에 task가 있는지 반복하여 확인하다. 만약 Call Stack이 비어있다면 Event Queue 내의 task를 Call Stack으로 이동하고 실행한다.
이벤트 루프(Event-Loop) 예제
이벤트 루프(Event-loop) 코드는 다음과 같이 실행된다.
1) main 함수에 대한 호출이 먼저 CallStack에 Push 된다.
2) 브라우저가 main 함수 내에 console.log('A')를 stack에 넣는다.
3) console.log('A')가 실행되자마자 stack에서 Pop이 되고, 'A'가 콘솔에 표시된다.
4) setTimeout 함수가 CallStack에 Push 된다.
5) setTimeout 함수는 콜백을 delay하기 위해 Browser API를 사용한다.
6) 콜백이 브라우저로 넘어가면, setTimeout 함수는 Pop이 된다.
7) 타이머 함수가 돌아가는 중 console.log('C')가 CallStack에 Push 된다.
8) 제공된 delay가 0ms 였기 때문에, Browser가 콜백을 받자마자 Event queue에 추가된다.
9) console.log('C')가 Pop되자 마자 main함수도 Pop이 된다. 콜 스택은 빈(empty) 상태가 된다.
10) Browser가 Event queue에서 콜 스택으로 Push하기 위해서는 콜 스택이 빈(empty) 상태가 되어야 한다.
* delay가 0ms였음에도 불구하고, 먼저 작동하지 않은 이유는 여기에 있다. setTimeOut에 들어가는 delay 파라미터는 함수가 실행되고 난 뒤 delay에 대한 시간을 말하는 것이 아닌, 최소 대기시간을 의미한다.
11) display 함수가 콜 스택에 Push 되고 실행되고, 그 다음 console.log('B')가 콘솔에 표시된다.
JavaScript가 싱글스레드임에도 불구하고, 비동기 방식으로 작동할 수 있는 이유는 이벤트 루프(Event-loop)를 이용한 이벤트 드리븐(Event-Driven)방식을 적용했기 때문이다.
다음은 V8엔진의 코드 변환 방법에 대한 기록이다.
< 참고자료 >
https://github.com/leonardomso/33-js-concepts
<ES5 series> chapter 8, 이벤트 루프(Event loop) end
'Language & Framework & Library > JavaScript' 카테고리의 다른 글
ES5 .Intro(11) - setTimout & setInterval (0) | 2019.12.28 |
---|---|
ES5 .Intro(10) - V8 엔진 코드 변환 방법 (0) | 2019.12.20 |
ES5 .Intro(8) - IIFE (0) | 2019.12.18 |
ES5 .Intro(7) - 호이스팅(Hoisting) (0) | 2019.12.17 |
ES5 .Intro(6) - 스코프(Scope) (0) | 2019.12.14 |