Front-End 면접 질문 대비 Part5 (JavaScript 이벤트 루프, 비동기 처리)

holim0·2021년 2월 7일
8

직무 면접 대비

목록 보기
5/6
post-thumbnail

이번 글에서는 자바스크립가 어떻게 동작을 하는지, 이벤트 루프 중심으로 살펴보겠습니다! 🧐


이벤트 루프

➡️ 아래 그림을 통해 전체적인 자바스크립트 동작원리를 파악할 수 있습니다.

출처: https://blog.sessionstack.com/how-does-javascript-actually-work-part-1-b0bacc073cf

JavaScript Engine

✅ 자바스크립트 엔진은 위의 그림에서 확인할 수 있듯이 Memory Heap과 Call Stack으로 구성되어 있습니다.

자바스크립트는 싱글 스레드(Single Thread) 프로그래밍 언어로 이는 Call Stack이 한 개임을 의미합니다. 가장 유명한 자바스크립트 엔진으로는 구글의 V8 엔진을 말할 수 있습니다.

  • Memory Heap: 메모리 할당이 이뤄지는 곳입니다.

  • Call Stack: 코드가 실행될 때 호출 스택이 쌓이는 곳입니다. (호출된 함수가 call stack에 push 됩니다.)


Web APIs

✅ 자바스크립트 언어 자체가 비동기 동작을 지원하는 것은 아닙니다. 비동기로 동작하는 핵심 요소는 브라우저가 가지고 있습니다.

브라우저는 Web APIs, Event Table, Callback Queue, Event Loop 등으로 구성되어 있습니다. 위의 그림에서 오른쪽에 해당하는 Web APIs가 브라우저가 제공하는 API입니다.

Web API에는 DOM, Ajax, Timeout(setTimeout) 등이 존재합니다.

  • Call Stack에서 실행된 비동기 함수는 Web API를 호출하게 됩니다.
  • Web API는 콜백함수를 Callback Queue에 밀어 넣습니다.

Callback Queue

✅ 비동기적으로 이벤트 발생 시 실행해야 할 callback 함수가 Callback Queue에 추가됩니다.


Event Loop

Event Loop는 Call Stack과 Callback Queue의 상태를 체크하여, Call Stack이 빈 상태가 되면, Callback Queue의 첫번째 콜백을 Call Stack으로 밀어넣어 줍니다. 이러한 반복적인 행동을 틱(tick) 이라 부릅니다.

💡 Event Loop와 Queue는 자바스크립트 엔진이 하나의 코드 조각을 하나씩 처리할 수 있도록 작업을 스케줄하는 동시에 자바스크립트에서 비동기 작업을 할 수 있도록 해줍니다.

하나의 예시를 보고 가겠습니다.


console.log('first');
setTimeout(
    function f2() { 
        console.log('second'); 
    }
, 0);

f3();
console.log('third');

  
function f3() {
    // do Something
}

결과는 다음과 같습니다.

first
third
second

➡️ f2() 함수가 **Callback Queue**에 있는 시점에 **Call Stack**에는 **f3()**이 들어가 있기 때문에 Event Loop 는 **Callback Queue**를 체크하지 않습니다.

**f3()**가 종료된 후에는 **console.log('third');**가 **Call Stack**에 추가되어 먼저 출력이 되는 것입니다.



비동기 처리(Promise)

Microtask Queue (ES 최신 2019 기준으로 Job Queue)

➡️ Event Loop는 제일 우선적으로 Microtask Queue 확인하고 작업이 있다면 Call Stack으로 push 합니다.

만약 Microtask Queue가 비어있다면 Task Queue를 다음으로 확인하게 됩니다.

출처: http://sculove.github.io/blog/2018/01/18/javascriptflow/

💡 Promise를 사용할 경우에는 _Microtask Queue_를 사용하게 됩니다. _Promise_에서 callback 함수 역할을 하는 .then을 사용하게 되면 _Microtask Queue_에 추가되는 것입니다.

대표적인 예시를 통해 살펴보겠습니다.


console.log('start'); 

setTimeout(function() {
  console.log('setTimeout');
}, 0);

Promise.resolve().then(function() {
  console.log('promise1');
}).then(function() {
  console.log('promise2');
});

console.log('end');

결과는 아래와 같이 나오게 됩니다.

start
end
promise1
promise2
setTimeout

_Promise_의 .then()의 콜백은 우선 순위가 가장 높은 Microtask Queue에 담기게 됩니다.

따라서 우선순위가 높은 Microtask Queue부터 처리되므로, _Promise_의 .then() 콜백이 다 실행되고, setTimeout 콜백이 실행되어 위와 같은 결과를 가지게 되는 것입니다.


마무리

오늘은 자바스크립트에서 매우 아주 중요한 동작원리와 이벤트 루프, 비동기 처리에 대해서 살펴보았습니다!

중요하게 짚고 넘어가야 할 것 같습니다! 🔥


Reference

  • https://engineering.huiseoul.com/자바스크립트는-어떻게-작동하는가-이벤트-루프와-비동기-프로그래밍의-부상-async-await을-이용한-코딩-팁-다섯-가지-df65ffb4e7e
  • https://medium.com/sjk5766/javascript-비동기-핵심-event-loop-정리-422eb29231a8
  • https://asfirstalways.tistory.com/362
profile
매일 조금씩 성장하고 있는 개발자입니다.

0개의 댓글