[JS] 이벤트 루프(Event Loop)와 동시성(Concurrency)

jiseong·2021년 8월 4일
4

T I Learned

목록 보기
19/291

이벤트 루프(Event Loop)와 동시성(Concurrency)

  • 자바스크립트는 싱글 스레드 프로그래밍 언어이다. 그렇기 때문에 하나의 작업만을 처리 할 수 있다. 하지만 실제로 웹 브라우저를 사용하다 보면 여러 작업이 동시에 진행되는 것처럼 느껴진다. 이는이벤트 루프를 통해 동시성을 지원하기 때문이다.
    one thread == one call stack == one thing at a time

  • 여기서 동시성(Concurrency)이란? 실제 물리적으로 동시에 일어나는 것이 아니라, 흐름을 실행시키는 것은 하나이며 작은 단위로 흐름을 돌아가면서 실행시켜 동시에 일어나는 것 처럼 보이게 하는 방식이다.

일반적으로 대부분의 브라우저에는 모든 브라우저 탭에 대해 이벤트 루프가 존재하며 브라우저의 환경을 그림으로 나타내면 위와 같이 나타낼 수 있다.

  • 1) JavaScript engine

    자바스크립트 엔진은 두 가지 주요 구성요소가 있다.

    • Call Stack
      실행되는 순서를 기억하고 있는 영역으로 함수의 호출을 기록하는 자료구조이다. (LIFO 원칙)
    • Heap
      동적으로 생성된 객체의 인스턴스가 할당되는 영역
  • 2) Web APIs
    DOM, AJAX, setTimeout 등 브라우저가 제공하는 API이다.

  • 3) callback queue
    비동기 처리 함수의 콜백 함수, 비동기식 이벤트 핸들러, Timer 함수(setTimeout(), setInterval())의 콜백 함수가 보관되는 영역이다.

  • 4) Event loop
    Call Stack과 callback queue의 상태를 반복적으로 체크하다가 Call Stack이 비어있게 되면 callback queue 내의 첫 번째 task를 Call Stack으로 이동시킨다.




아래 예시코드를 통해서 이벤트루프가 어떻게 동시성을 지원하는지 보자

📝 예시 코드

console.log('Hi jiseong');

setTimeout(function cb(){
    console.log('there');
},5000);

console.log('Hello');
1. 코드가 실행되기 전의 상태이다. call stack과 callback Queue는 비어있다.

2. 코드가 실행되면 Call Stack에 console.log('Hi Jiseong')가 push된다. (main()은 생략했다.)

3. console.log('Hi Jiseong')가 실행되며 브라우저 console에는 Hi jiseong이 찍힌다. 그 후, 함수가 종료되며 Call Stack에서 pop된다.

4. Call Stack에 setTimeout(function cb() { ... })가 push된다.

❓ 참조
setTimeout은 브라우저가 제공하는 API중 하나로 특정 코드를 사용자의 의도에 따라 시간을 지연시켜주는 함수이다.

5. setTimeout은 자바스크립트 엔진에서 처리하지 않고 바로 web APIs로 넘어가고 브라우저는 해당 타이머를 생성한다.

6. Call Stack에 console.log('Hello')가 push된다.

7. console.log('Hello')가 실행되며 브라우저 console에는 Hello이 찍힌다. 그 후, 함수가 종료되며 Call Stack에서 pop된다.

8. 5000 ms후에, 타이머가 종료되고 cb()함수는 Callback Queue로 넘어간다.

9. Event Loop는 Call Stack이 비어있기 때문에 해당 함수를 Call Stack로 넘긴다. 그 후, cb()함수가 실행되며 내부에 있는 console.log('there')를 call stack에 push한다.

10. console.log('there')가 실행되며 브라우저 console에는 there이 찍힌다. 그 후, 함수가 종료되며 Call Stack에서 pop된다.

11. cb()함수가 종료되며 Call Stack에서 pop 되면서 모든 수행이 종료된다.

여기서 setTimeout함수를 통해 서버로 부터 대략 5초정도를 기다려 뭔가를 받는 시뮬레이션을 해봤다. 만약 Event Loop가 없었다면, 서버로 부터 데이터를 받을 때 까지 기다려야하는 blocking 상황이 벌어졌을 것이다.


Reference

0개의 댓글