[Java Script] 이벤트 루프🔄 너란 녀석🤷🏻‍♂️

June hyoung Park·2020년 8월 1일
1

JavaScript

목록 보기
1/18
post-thumbnail

Java Script 는 코드 실행, 이벤트 수집과 처리, 큐에 놓인 하위 작업들을 담당하는 이벤트 루프에 기반한 동시성(concurrency) 모델을 가지고 있습니다. 이 모델은 C 또는 Java와 같은 언어와 완전히 다릅니다.
- developer.mozilla.org

Java Script 를 공부하고, 사용하다 보면 그 특유의 유연함 덕분에 이해하기 힘든 일들이 벌어 지거나, 손에 익어 사용 할 줄은 알지만, 어떻게 동작하는지 머릿속으로 그리기 힘든 상황이 많이 생긴다.

그중 가장 이해하기 힘들었던것이 콜스택, 그리고 비동기 작업이 어떻게 처리되는가 였는데, 이 글을 통해 지금까지의 약소한 깨우침을 정리해보려 한다.

콜스택 🗂

Java Script 싱글 쓰레드(single-threaded) 언어이다. 즉 콜스택이 하나이기에 한 번에 한가지의 작업만을 수행할 수 있다.

Stack, Heap, Queue, Event-Loop 등등 Java Script 동작 원리에 대해 관심이 있다면, 한번쯤은 들어 보았을 단어 들이다. 이 글의 핵심인 비동기 작업 처리에 대해 이해하려면 우선 Java Script 의 동작 원리에 대해 전반적으로 알고있어야한다.

위 사진을 보면 메모리 할당이 일어나는 힙과, 콜스택이 보이는데 콜스택은 기본적으로 함수의 호출을 기록하고, 호출 순서를 기억하는 자료구조이다. 즉 코드가 작동되면서 함수가 호출되면, 해당 함수는 스택의 가장 위에 놓이게되고, 만약 그 함수가 다른 함수를 호출 한다면 또 그위에 쌓이게된다.

그리고 각 함수가 실행 후 리턴 될때는 실행 순으로, 즉 콜스택의 가장 윗 부분 차례로 지워지는것이다.

이벤트 루프와 큐 🏁

위 그림은 이벤트 루프를 가장 잘 표현한 그림이라고 생각한다. 왼쪽 상단엔 위에서 언급한 Heap과 Stack이, 그리고 오른쪽 상단엔 브라우저가 제공하는 DOM, Ajax, setTimeout 와 같은 웹 API가 보인다.

브라우저측에서 제공하는 웹 API가 있기에, 한번의 하나의 코드만 실행할 수 있는 싱글 쓰레드 언어인 자바스크립트는 동시성을 가질 수 있다.

Loupe(http://latentflip.com) 는 브라우저에서 자바스크립트가 어떻게 동작하는지 가장 쉽고 직관적으로 보여주는 사이트다. 접속하게되면 샘플 코드가 타이핑 되어 있는데, 샘플 코드를 통해 자세히 알아보자.

위 코드를 실행시키면 어떤 결과가 출력될지 예측해보자. 5번 라인 까지는 이벤트 호출 메소드이니 특정 버튼을 누르지 않는 이상 실행되지 않을것이며, 콘솔창엔 7번 라인의 "Hi!"가 출력되고, 13번라인의 "Welcome to loupe."가 출력된 후 대략 5초 쯤 후에 "Click the button!"이 출력 될것이다.

어찌보면 당연한 결과이고, 익숙한 결과이다. 하지만 동작 원리상 어떻게 이런 결과가 나타나는 것일까?


먼저 코드 가 실행되면 5번 라인 까지의 함수가 호출되고, 콜스택에 쌓이게 된다.

처음 콜 스택에 올라온 함수가 인자로 갖고있는 콜백 함수는 당연히 콜백 실행 조건인 'click'을 하지 않았기에 작동되진 않았겠지만, 호출 자체는 끝났기때문에 바로 콜 스택에서 지워지게 된다. 그러나 비동기 메서드 이기에, 웹 API로 넘어가게 된다.

그 후 console.log("Hi!")가 호출되어 콜 스택에 쌓인 후 콘솔창엔 "Hi!"가 출력되고, 콜스택에서 지워지고, 다음 차례로 호출된 setTimeout 역시 호출 후 지워진다. 다만 비동기 메서드 이기에 위의 이벤트 메서드 처럼 웹 API로 넘어가게된다.

그러나 첫번째로 넘어간 '$.on~~' 이벤트 메서드와는 달리 즉시 실행 조건 없이 5초 후에 실행되게끔 되어있기에, 웹 API 단에서 5초의 카운트 다운이 진행 된 후 다음 단계인 콜백 큐로 넘어가게된다.

먼저 콜백 큐에 대해 간략히 설명하자면, 콜백 함수들이 대기하는 큐(FIFO) 형태의 배열이다.
자, 그럼 이제 어떤 일이 생길까?

콜백 큐에 있던 timeout()콜 스택으로 올라간것이 보인다. 여기서 우린 이벤트 루프가 어떤 기능을 수행하는지 알수있는데,

이벤트 루프는 콜 스택과 콜백 큐를 주시하는 것이다. 콜스택에 쌓여있던 함수가 리턴 후 스택이 비게되면 이벤트 루프는 콜백 큐에 대기중인 콜백을 콜스택에 쌓아주는 역활을 하는것이다.


정리를 마치며 🥳

console.log('first');

setTimeout(()=>{
    console.log('second');
},0);

console.log('third');

//first
//third
//second

이제 이벤트 루프가 이해됬다면, 두개의 console.log 사이의 위치한 setTimeout의 지연시간이 0초로 설정 되어있음에도 불구하고, 콘솔창에 'first -> third -> second' 순으로 출력되는지 이해할 수 있을것이다 🥳

profile
Take me home~~~~

0개의 댓글