기술면접을 준비하면서 공부했던 내용들을 정리하고자 오랜만에 블로그에 들어왔습니다.

이번 글에서는 자바스크립트 동작에 대해서 글을 적어보려고 합니다.

 

1.  JavaScript

이전에 자바스크립트에서 작성한 글이 있지만 해당 글을 이해하기 위해서 간단하게 알고 넘어가야하는 개념이 있습니다.

자바스크립트는 싱글 스레드 언어입니다. 따라서 명령어 여러개를 동시에 처리하는 것이 아니라 한줄씩 처리할 수 있습니다.

 

2. JavaScript 구성

JavaScript 동작 출처: google Javascript엔진 검색

자바스크립트 동작을 이해하려면 자바스크립트 엔진, Web API, queue, Event Loop으로 구성되어 있습니다.

 

2-1. 자바스크립트 엔진

자바스크립트 엔진에는 heap과 stack이 있습니다. heap에는 원시타입, 객체타입이 선언이 되면 메모리 힙에 할당이 되고, 사용이 끝나면 자동으로 힙에서 해제됩니다. stack은 실행해야하는 코드인 실행 컨텍스트가 쌓입니다. 코드 실행시 push, 실행이 끝나면 pop이 됩니다.

여기에서 실행 컨텍스트란 실행가능한 코드가 실행되기 위해서 필요한 환경을 모아놓은 객체입니다. 기본적으로는 글로벌 컨텍스트가 스택 가장 아래 쌓이고 그 다음으로 함수 컨텍스트 들이 위로 차례로 쌓입니다.

 

2-2. Web API

Web API에는 Ajax 요청, SetTimeout, setInterval, 이벤트 핸들러의 등록과 같은 웹 브라우저에서 제공하는 기능들입니다. 해당 기능들은 그립과 같이 자바스크립트 엔진과는 떨어져 있는 것을 확인할 수 있습니다.

 

2-3. Queue

다음으로는 Queue 입니다. Queue라고 하면 선입선출, 먼저 들어온 객체가 먼저 나가는 자료구조입니다. 그림에는 Callback queue만 있는데 사실은 Callback queue를 포함해서 MicroTask queue, Animation Frame이 추가로 해서 3개의 queue가 있습니다.

 

우선 Callback queue는 MacroTask queue 또는 Task queue라고도 불립니다. 해당 queue는 Ajax, setTimeOut, setInterval, setImmediate와 같은 task의 결과를 넘겨 받습니다. 우선순위는 3개의 queue중에서 가장 낮습니다.

 

다음으로는 MicroTask queue입니다. 해당 queue는 promise, async/await, process.nextTick 과 같은 비동기 호출을 넘겨 받습니다. 3개의 queue중에서 우선순위가 가장 높습니다.

 

다음으로는 AnimationFrame입니다. requestAnimationFrame과 같은 브라우저 렌더링과 관련된 task를 넘겨받습니다. 3개의 queue중에서 우선순위가 2번째로 높습니다.

 

정리해보면 queue는 총 3개가 있으며 우선순위는 MicroTask queue > AnimationFrame > MacroTask queue 입니다.

 

이해가 잘 안되신다면 아래 블로그 글을 참고하시면 좋을거 같습니다!

https://velog.io/@titu/JavaScript-Task-Queue%EB%A7%90%EA%B3%A0-%EB%8B%A4%EB%A5%B8-%ED%81%90%EA%B0%80-%EB%8D%94-%EC%9E%88%EB%8B%A4%EA%B3%A0-MicroTask-Queue-Animation-Frames-Render-Queue

 

[JavaScript] Task Queue말고 다른 큐가 더 있다고? (MicroTask Queue, Animation Frames)

자바스크립트에서 비동기 함수가 동작하는 원리에 대해서 공부했다면, Task Queue에 대해 들어보았을 것이다. Task Queue는 Web API가 수행한 비동기 함수를 넘겨받아 Event Loop가 해당 함수를 Call Stack에

velog.io

2-4. Event Loop

Event Loop은 Stack이 비어져 있으면 Queue에서 대기중인 작업을 Stack으로 올려줍니다.

 

3. 동작

간단한 개념들을 익혔으니 이제는 동작을 알아보겠습니다.

console.log("start")

setTimeout(function() {
  console.log("setTimeout")
}, 0)

promise.resolve()
.then(functuon() {
  console.log("promise")
})

console.log("end")

여러분들은 이 코드의 결과가 어떻게 나올거 같으신가요? 정답은 아래와 같이 나옵니다.

start
end
promise
setTimeout

1. 우선 Stack 가장 아래에는 글로벌 컨텍스트가 쌓입니다.

2. console.log("start")가 Stack에 push되고 실행이 될 것입니다. 실행이 되면 Stack에서 pop됩니다.

3. 그 다음 실행인 setTimeOut()이 Stack에 쌓입니다. 이제 setTimeOut이 실행이되야하는데 위에서 setTimeout은 Web API 중 하나입니다. 따라서 순서가 이전 console.log()랑 다릅니다. 우선 Stack에서 pop이 되고난 다음 Web API setTimeout에게 실행하라고 신호를 보냅니다. 그러면 Web API에서 setTimeout을 실행시킵니다. setTimeout이 자바스크립트 엔진이 아닌 Web API에서 실행이 되면서 Stack에는 promise.resolve()가 스택에 push되는 것입니다. 이렇게 비동기 처리가 싱글스레드에서 일어나는 것입니다.

setTimeout의 실행이 끝나면 결과인 console.log("setTimeout")은 MacroTask queue에 들어가게 됩니다.

4. 이 과정이 일어나면서 Stack에서는 promise.resolve()를 실행 시킵니다. Stack에서 pop이되고 결과인 then()이 MicroTask queue에 들어가게 됩니다.

5. 마지막으로 console.log("end")가 Stack에 push되고 실행이 된 다음 Stack에서 pop됩니다.

6. 이제 더이상 실행할 코드가 없기 때문에 글로벌 컨텍스트가 pop되고 Stack은 비워집니다.

 

여기까지보면 console 창에는 start, end 만 적혀 있습니다

7. 이제 Event Loop가 Stack이 비워져 있는 것을 확인하고 Queue를 확인합니다. 우선 MicroTask queue에 있는 promise.resolve() 결과인 then()을 Stack에 Push시킨 뒤 코드를 실행하여 console에 promise가 추가됩니다. 그 다음 Stack에서는 pop됩니다.

8. AnimationFrame에는 아무 것도 없고 마지막으로 MacroTask queue에 있는 setTimeout() 결과를 Stack에 Push하고 실행시킨 뒤 pop합니다. 

 

이렇게 모든 코드가 동작했습니다.

뭔가 말로 적어서 조금 난잡하긴 한데, Queue에서 링크 걸어드린 블로그를 참고하시면 많은 도움이 되실거 같습니다.

'언어 > JavaScript' 카테고리의 다른 글

JavaScript와 Node.js  (1) 2020.11.21

1. 배경

 지금 캡스톤(졸업 작품)에서 아무 생각없이 JavaScript, Node.js, React, React Native를 사용하면서 갑자기 이들의 차이가 뭘까라는 생각이 들었다. '만약 면접에서 이런 질문이 들어오면 내가 뭐라고 대답할 수 있을까?' 라는 생각을 해보니 대답할 수 없을거 같더라.. 뭔가 이런 것을 생각한다는 자체가 바보같은 생각이라고 들때도 있지만 모르는게 죄는 아니잖아;; 지금부터라도 알고 써야지

 그래서 이번 글에서는 이 세가지가 어떤 차이가 있는지에 대해서 정도만 알아보고자 한다. 한번 알아보는 김에 깊고 정확하게 이해하는 것도 중요하긴 하지만, 내가 이 언어쪽으로 직업을 가지거나, 주 언어로 사용을 하려는 생각이 없는데 자세하기 알기에는 안그래도 부족한 뇌 용량에 억지로 넣는 기분이다.

 

2. JavaScript

 쉽게 말하면 JavaScript는 프로그래밍 언어 중 하나이다. 즉 우리가 흔히아는 C, C++, Python, Java와 같은 언어라고 할 수 있다. 조금 더 깊이 들어가면 객체 기반의 스크립트 프로그래밍 언어이다.(스크립트 언어를 설명하기엔 주제가 벗어나니 나중에 따로 글을 쓰게 된다면 링크를 걸어두도록 하겠다.) 따라서 JavaScript는 스크립트 언어이기 때문에 특정한 프로그램 안에서만 동작할 수 있다. 보통 Chrome, FireFox, Safari, Explore 등등에서 사용 가능하다. Chrome에서 F12를 누르면 개발자 도구를 활성화 할 수 있다. F12를 눌렀을 때 여러가지 탭이 있는데 console에서 JavaScript언어를 작성하면 동작하는 것을 확인할 수 있다.

 흔히 우리는 JavaScript를 말하면 무엇이 떠오르는가? 나 같은 경우에는 JavaScript를 한번도 사용해보지 않았는데도 그냥 자연스럽게 CSS, 웹, 홈페이지 등등이 떠올랐었다. 왜 프로그래밍 언어인데 웹에 관련된 단어들이 떠올랐을가? JavaScript도 웹이랑 밀접하게 관련되어 있기 때문이다. HTML이 웹 페이지의 기본 구조를 담당하고 CSS가 웹의 디자인을 담당한다면 JavaScript는 웹 페이지가 동작하는 것을 담당한다고 할 수 있다.

 JavaScript의 장점이라고 하면 확장성이 매우 뛰어난 언어이다. JavsScript만 알면 일반적인 웹 사이트 개발은 거의 할 수 있다. React.js, Vue.js, React Native 등등 다양한 라이브러리를 사용할 수 있다. 물론 그 안에서는 일반적인 JavaScript와 조금은 다른 부분들이 있지만 거의 비슷하다고 할 수 있다. 비전공자들이 이쪽 분야로 넘어왔을 때 가장 쉽게 배울 수 있는 것이 웹 관련 Front 쪽이라는 것이라고 보면 얼마나 쉽고 빠르게 배울 수 있는 언어인지 상상이 될 것이다.

 

3. Node.js

 좋아. 그럼 JavaScript는 프로그래밍 언어 중 하나인 것은 알겠는데 JavaScript를 뜻하는 js를 확장명으로 달고 있는 Node.js는 뭐가 다른걸까?

 Node.js를 이해하기 위해선 JavaScript를 먼저 배우긴 해야한다. 왜냐하면 Node.js는 JavaScript 기반으로 만들어졌기 때문이다.  Node.js는 Chrome V8 JavaScript 엔진으로 빌드된 JavaScript 런타임이다. JavaScript는 Chrome, FireFox 등등 웹 브라우저에서 동작할 수 있지만 이러한 웹 브라우저가 없으면 사용할 수 없는 단점이 존재했다. 우리는 이러한 웹 브라우저 뿐만 아니라 terminal(윈도우에서는 cmd) 같은 곳에서도 사용하거나 디버깅하고 싶은데 그럴 수 없었다는 뜻이다. 하지만 Node.js는 terminal와 같은 외부 환경에서도 실행이 가능하다. 또한 Node.js를 활용해 서버를 만들 수 있다.

 Node.js에는 여러 패키지들이 있는데 npm(Node.js Package Manager)로 관리가 된다. Python의 pip install로 Python 패키지를 설치하는 것처럼 비슷하다. npm install을 이용해서 Node.js에 관련된 패키지를 설치할 수 있다. Facebook에서 만든 yarn이라는 패키지 및 배포 관리자도 있는데 npm과 성능 측면에서는 큰 차이가 없다는거 같다.

 

4. React

 React는 React.js, ReactJS라고도 불리며 JavaScript의 라이브러리 중 하나로 웹 및 앱을 개발 할 수 있다. Facebook 및 여러 공동체에 의해 유지보수가 되고 있다.

 React를 사용하면 React를 지원해주는 여러 컴포넌트 관련 라이브러리를 쉽게 사용할 수 있다. 예를 들면 버튼을 구현할 때 디자인을 손보고 싶으면 Css를 통해서 수정해야했다면, Ant Design 등의 라이브러리 등을 사용하여 해당 라이브러리에서 제공하는 Button이나 여러 컴포넌트들을 사용할 수 있다. 

 React는 JavaScript의 라이브러리 중 하나이지만 사용해보면 State와 Props 개념의 등장으로 조금은 다른 부분이 있다는 것을 느낄 것이다. 글쓴이도 처음 React를 만질 때 State, Props 이해하느라 머리가 아팠다는.. 이 글은 React를 설명하는 글은 아니다 보니 필요하신 분들은 따로 찾아보시길 바랍니다. 그래도 이 두가지를 이해하면 쉽게 웹 페이지를 개발할 수 있고, 익숙해지면 대충 이런식으로 하면 되겠구나를 생각할 수 있는 자신을 발견할 것이다.

 React는 document 사이트도 잘 되어 있고 요즘은 많이 사용하고 있어서 처음 접하더라도 쉽게 배우고 따라갈 수 있을 것이다.

 

5. React Native

 React Native도 Facebook이 개발한 오픈 소스 모바일 애플리케이션 프레임워크이다. 안드로이드, iOS, 등의 어플리케이션을 개발하기 위해 사용되며 네이티브 플랫폼 기능과 React를 사용할 수 있게 한다.

 React Native도 JavaScript 기반으로 작성하므로 나름(?) 쉽게 배울 수 있을거 같지만 초기에 꽤 많은 오류를 접한다. 특히 React Native 오류가 나면 앱에 빨간 배경에 오류 글씨가 가득차는데 정말 꼴보기 싫다... 뭔가 게임 속에서 스토리 진행하다가 죽었을 때 You DIE 문구가 나타나는 기분이랄까..?

 대학교 2학년 때(2018년) 첫 팀프로젝트에서 모바일 어플리케이션을 개발할 때 처음으로 React Native를 사용해보았는데 생각보다 답답한 점이 많았다. 우선 에러가 나더라도 어느 이유에서 에러가 나왔는지 쉽게 이해할 수 없었다.. 물론 나중에 React Native에 대해서 익숙해지고 나면 '아..? 여기에서 실수했겠구나' 정도로 이해할 수 있지만 처음 개발하는 사람들에게 에러 문구를 보여주면 '음..? 이게 뭔말이여?' 라는 생각이 들게 만든다. 또한 document 사이트가 지금은 개선이 되어있는지 모르겠지만 당시에는 '이게 다야..?' 라는 말이 나왔다. stackoverflow 등에 검색해봐도 해결이 잘 안되는 경우도 많았고, 책을 사서 공부하려고해도 React Native에 관련된 책이 거의 없었다. 학교 도서관에 1권 있었는데 별 도움이 되진않았던 걸로 기억된다. 요즘은 사용하는 기업이나 시도하는 사람들이 많아서 조금은 관련 정보들이 많을 것으로 예상이 된다. 이전에 React를 만져보았다면 React Native를 다루는데 많은 도움이 될 것이다.

 

6. 결론

 오늘은 JavaScript와 관련된 라이브러리, 플랫폼을 알아보았다. 배경에서도 말했지만 JavaScript를 주 언어로 사용할 것이 아니라면 이러한 차이들을 굳이 알아야할까? 라는 생각이 들긴한다. 하지만 안다고해서 나쁠거야 없다. 예상하지 못한 상황에서 갑자기 사용하게 될 수도 있고, 누군가가 너 이런거 알아? 라고 했을 때 아는 척이라도 할 수 있다.

 

많이 부족한 내용이지만 읽어주신 분들 감사합니다.

'언어 > JavaScript' 카테고리의 다른 글

자바스크립트 동작  (0) 2023.09.14

+ Recent posts