티스토리 뷰

자바스크립트는 싱글스레드 기반의 Non-blocking으로 동작한다, 비동기이다 이런 말들은 많이 들어봤지만 정확히 어떤 원리때문에 이렇게 말할 수 있는지 자세히 알지 못했습니다. 그래서 자바스크립트의 이러한 동작방식에 중요한 요소들인 call stack, event queue, event loop에 대해서 알아보고자 합니다!!

 

call stack, event queue, event loop에 대해서 알아보기전에 기본적으로 자바스크립트가 무엇인지 알 필요가 있을 것 같다고 생각하였습니다.

 

우선, 시작하기 전에 자바스크립트 환경의 전반적인 그림을 보고 가면 이해하는데 더 도움이 될 것 같습니다.

 

출처 :  https://cdn-images-1.medium.com/max/1600/1*FA9NGxNB6-v1oI2qGEtlRQ.png

 

자바스크립트

  • 단일 쓰레드
  • 자바스크립트 엔진 중에 유명한 것이 있는데 V8엔진이다.
  • V8은 크롬과 노드JS에서 사용되고 있다.
  • 자바스크립트 엔진은 보통 자바스크립트 코드를 실행하는 프로그램, 인터프리터를 뜻한다.
  • V8엔진은 크게 두 부분으로 구성된다.(메모리힙 / 콜스택)

여기서 메모리힙과 콜스택은 다음과 같습니다.

 

메모리힙

  • 메모리 할당이 동적으로 일어나는 곳
  • 배열을 생성하거나 객체를 생성할 때. 즉, 원시값을 제외한 메모리에 주소값이 할당되어 참조를 해야되는 경우에는 모두 힙에 저장이 된다.

 

Call Stack, 콜스택

  • 코드가 실행되면서 스택 프레임이 쌓이는 곳(스택 프레임은 콜스택에 각각 쌓이는 작업들)
  • 싱글스레드이기에 하나만 존재. 즉, 한 번에 하나의 일만 함
  • 프로그램의 어느 위치에 있는지를 기록하는 자료구조
  • 에러가 발생했을 때 확인할 수 있는 Stack trace는 그 당시의 스택프레임을 추적해 나간 것임.
  • Blowing the Stack : 재귀함수로 인해 발생. 스택의 크기를 초과하여 함수가 호출
  • 스택에서 실행되는 함수가 처리되는데 긴 시간이 걸린다 > 다른 작업을 할 수 가 없으므로 브라우저가 멈추게 됨(UI작업도 마찬가지)
  • 위와 같은 현상을 해결하기위해 비동기 콜백을 사용하고, 그 도움을 주는 요소들이 바로 event queue, event loop 이다.

하나의 콜스택에서 작업을 수행하는 단일 쓰레드는 단점이 존재합니다. 콜스택 내부에서 시간이 오래 걸리는 작업이 실행되고 있는 경우, 다른 작업은 그 작업이 끝날 때 까지 기다리는 Blocking 상태가 됩니다.

 

예를들어, 데이터통신을 하는 함수가 실행된다고 하면 이 함수가 콜스택내에서 실행중이면 UI를 렌더랑하는 함수를 이 함수가 끝날 떄까지 호출되지 못하므로 페이지가 멈춰버리는 현상이 발생합니다. 실제 서비스에서 이러한 현상은 치명적이라고 할 수 있습니다.

 

싱글 스레드에서 발생하는 이러한 문제들은 Event loop와 Event queue를 이용하여 해결됩니다. 그러면 이제 Event loop와 Event queue에 대해서 알아보겠습니다.

 

Event loop

  • 이벤트 루프는 콜스택과 이벤트큐를 감시
  • 콜스택이 비어있고 이벤트큐에 작업이 있으면 제일 앞에 있는 작업을 콜스택에 추가
  • 이러한 반복을 tick이라고 함
  • MDN에 설명되어 있는 event loop에 대한 가상의 코드를 참고하면 이해하기 쉽다
while(queue.waitForMessage()) {
	queue.processNextMessage();
}

출처

 

앞서 설명한 것처럼 자바스크립트 엔진(ECMAScript)에는 heap과 call stack 만 속하고 event loop는 자바스크립트 엔진이 동작하는 환경에 속한 것입니다. Node.js에서는 libuv라는 라이브러리가 존재하고 브라우저에서는 따로 모듈이 존재한다고 합니다. 그렇기 때문에 자바스크입트 엔진 자체는 싱글 스레드이고 구동되는 환경(Node.js, 브라우저 ...)은 다중 스레드라고 할 수 있습니다.

 

Event queue

  • 콜백함수나 비동기적으로 실행되는 함수들이 쌓여 호출되기룰 기다리는 공간.
  • 보통 Web API와 연계되어 인자로 넘어간 콜백함수들이 추가됨.
  • Web API는 우리가 아는 DOM, AJAX, setTimrOut 같은 호출만 가능한 함수들이 있음.
  • 즉, ajax를 이용해 통신을 한다고 하면 인자로 넘긴 콜백함수가 ajax의 함수가 실행되고 난 뒤에 이벤트 큐에 추가되는 방식

아래의 코드를 보면 전반적인 콜스택, 이벤트 루프, 이벤트 큐의 동작 흐름을 알 수 있습니다.

// 콜백함수 : 이벤트큐에 추가
function callback() {
	console.log("event queue!");
}

setTimeout(callback,1000) // Web API 호출, 1초 지연후 실행

console.log("call stack!");

위의 코드는 다음과 같은 순서로 동작됩니다.

 

  1. setTimeout(WEB API) 함수 실행
  2. setTimeout이 비동기적으로 처리(콜스택은 계속해서 실행중)
  3. 1초가 지난 뒤 인자로 넘어온 콜백을 이벤트 큐에 추가
  4. 이벤트 루프는 콜스택을 감시하고 콜스택이 비어지면 이벤트 큐에서 제일 오래된 작업을 빼서 콜스택에 추가
  5. 콜스택은 작업을 처리

콘솔에 "call stack!"이 먼저 출력되고 1초 뒤에 "event queue!"가 출력되는 것을 확인할 수 있습니다!

 

 

참고사이트

https://engineering.huiseoul.com/자바스크립트는-어떻게-작동하는가-이벤트-루프와-비동기-프로그래밍의-부상-async-await을-이용한-코딩-팁-다섯-가지-df65ffb4e7e

https://blog.javarouka.me/2016/11/08/javascript-async-promise-1/#Timer

https://developer.mozilla.org/ko/docs/Web/JavaScript/EventLoop

 

'Javascript' 카테고리의 다른 글

[Javascript] 정규표현식  (0) 2019.08.06
[Javascript] Canvas API  (0) 2019.08.02
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함