자바스크립트 런타임 환경
Call stack과 event loop는 자바스크립트의 동작 원리를 이해하기 위해 꼭 숙지해야하는 개념이다. 자바스크립트가 실행되는 환경을 의미하는 자바스크립트 런타임 환경은 다음과 같이 구성되어 있다. 크게 Memory heap, call stack, web apis, callback queue, event loop가 있다.
Call Stack
Call stack은 함수의 호출을 저장하는 자료구조이다. 어떤 함수를 호출하면 스택에 쌓고 또 다른 함수를 호출하면 그 다음 스택에 쌓으면서 가장 위에 쌓인 함수를 가장 먼저 처리한다. 대표적인 예제는 다음과 같다.
가장먼저 func1을 호출하므로 call stack에 func1이 쌓인다. 그리고 func1에서 func2를 호출하므로 call stack에 func2가 쌓이고, func2에서 func3을 호출하므로 call stack에 func3이 마지막으로 쌓인다. Call stack에서는 가장 위에 놓인 함수를 가장 먼저 처리하므로 Call func3을 가장 먼처 출력하고 차례로 Call func2, Call func1이 출력된다.
Memory Heap
Memory Heap은 객체를 저장하는 곳이다. 예제에서 선언한 함수 func1, func2, func3는 모두 Memory Heap에 저장된다.
Web API
Web API는 브라우저에서 제공하는 API들이다. 위의 그림에서는 자바스크립트의 런타임환경을 설명하고 있기 때문에 web API가 등장했다. 만약 node js 런타임 환경을 설명했다면 다른 API로 표시했을 것이다. 대표적인 예시로는 setTimeout 함수가 있다.
Callback Que
Callback Que는 함수를 저장하는 자료구조이다. Call stack과 다르게 가장 먼저 들어온 함수를 가장 먼저 처리한다. 특정 이벤트에 따른 콜백 함수를 정의하면, 콜백 함수는 Callback Que에 저장된다.
Event Loop
Event Loop는 call stack이 다 비워지면 callback que에 존재하는 함수를 하나씩 호출 스택으로 옮기는 역할을 한다.
예제
자바스크립트 런타임 환경의 모든 요소를 확인할 수 있는 예제를 작성해보았다.
약 5초뒤에 '약 5초가 걸리는 함수'라는 문자열이 출력되고 바로 이어 '2초 뒤에 실행하는 콜백함수'라는 문자열이 출력된다. 이를 설명하기 위해 자바스크립트 런타임 환경에서 이 예제의 동작 과정은 설명하겠다.
먼저 func1을 호출하므로 call stack에 쌓는다. func1에서 setTimeout이라는 web api를 실행하면 func1의 함수를 모두 처리하게 된다. 바로 func1을 call stack에서 없애고 다음 함수인 func2를 call stack에 쌓는다.
func2 함수에서는 약 5초정도 걸리는 작업을 하게 된다. 이때 2초가 지나면 setTimeout에서 콜백함수로 설정한console.log() 함수를 호출하게된다. 이때 console.log() 함수는 2초가 지났다는 이벤트에 따른 콜백 함수이기 때문에 callback queue에 저장한다.
추가적으로 3초가 지나면 func2 함수내에서 약 5초정도 걸리는 작업을 마치고 console.log() 함수를 이용해서 '약 5초가 걸리는 함수'라는 문자열을 출력한다. 이후 func2 함수를 처리하였으므로 fubc2을 call stack에서 없애고 callback queue에 저장된 console.log() 함수를 call stack에 옮긴다.
최종적으로 call stack에 쌓인 console.log() 함수를 호출하여 '2초 뒤에 실행하는 콜백함수'를 실행하여 문자열을 출력한다. 이때 이미 2초라는 시간이 지난후 console.log() 함수를 호출한다는 내용만 call stack에 쌓여있으므로 func2의 함수가 처리되자마자 바로 문자열이 출력된다.
모든 처리가 끝난 후에는 다음과 같다.
참고자료
https://blog.sessionstack.com/how-does-javascript-actually-work-part-1-b0bacc073cf
'개발 공부 > JavaScript 공부' 카테고리의 다른 글
[JavaScript] async, await (0) | 2020.03.29 |
---|---|
[JavaScript] 프로미스(Promise) (0) | 2020.03.29 |
[JavaScript] Closure (클로저) (0) | 2020.02.18 |
[JavaScript] Spread syntax (전개 구문) (0) | 2020.02.17 |
[JavaScript] 스코프 - scope, lexical scoping, hoisting (0) | 2020.02.16 |