이벤트 루프(Event loop)

김민규·2022년 10월 5일
0

자바스크립트

목록 보기
6/7
post-thumbnail

참고
JavaScript Visualized: Event Loop

자바스크립트는 단일 스레드입니다. 한 번에 하나의 작업을 처리하죠. 작업이 금방 끝나면 상관 없지만, 오래 걸리면 그만큼 기다려야 합니다.

이를 해결하기 위해, 브라우저는 Web API를 제공합니다. async, non-blocking을 지원하는 API를 통해 단일 스레드의 한계를 극복하죠. 여기서 이벤트 루프가 등장합니다.

이벤트 루프를 알아보기 전에 함수와 콜 스택을 먼저 알아보겠습니다.

함수와 콜 스택

호출된 함수는 콜 스택에 추가되고 끝나면 빠집니다.(콜 스택은 자바스크팁트 엔진에 속합니다.)

function greet() {
	return 'Hello!';
}

greet 함수를 호출하면 어떻게 될까요?

  1. greet 스택에 추가, 실행(Hello 출력)
  2. greet 끝, 스택에서 빠짐

끝입니다. 간단하죠.

이벤트 루프

function greet() {
	return setTimeout(() => 'Hello!', 3000);
}

이번에는 Web API인 setTimeout을 호출합니다. 비동기 작업을 지원하는 setTimeout은 메인 스레드의 작업을 막지 않죠. 절차는 다음과 같습니다.

  1. greet 호출
    . 스택에 추가, 실행
    . setTimeout 호출, 스택에 추가, 실행
    . setTiemout은 콜백 함수를 Web API에 추가
    . setTimeout 끝, 스택에서 빠짐
    . greet 끝, 스택에서 빠짐
  2. 콜백 함수
    . Web API 타이머 3초가 지나면 콜백 함수를 큐(Macrotask Queue)에 추가
    . 이벤트 루프가 스택이 빈 것을 확인
    . 큐에서 콜백 함수를 꺼내 스택에 추가, 실행(Hello 출력)
    . 콜백 함수 끝, 스택에서 빠짐

이벤트 루프는 스택에 작업이 없으면 큐에 있는 작업을 꺼내 스택에 넣어주는 일을 하네요.

이제 필요한 것은 다 알았습니다. 좀 더 길어진 코드를 보겠습니다.

const first = () => console.log('First');
const second = () => setTimeout(() => console.log('Second'), 500);
const third = () => console.log('Third');

second();
first();
third();

결과가 어떻게 나올까요? 절차를 그려보면 답이 나옵니다.

  1. second 호출
    . 스택에 추가, 실행
    . setTimeout 호출, 스택에 추가, 실행
    . setTimeout은 콜백 함수를 Web API에 추가
    . setTimeout 끝, 스택에서 빠짐
    . second 끝, 스택에서 빠짐
  2. 콜백 함수
    . Web API 타이머 0.5초가 지나면 콜백 함수를 큐(Macrotask Queue)에 추가
  3. first 호출
    . 스택에 추가, 실행(First 출력)
    . 끝, 스택에서 빠짐
  4. thrid 호출
    . 스택에 추가, 실행(Thrid 출력)
    . 끝, 스택에서 빠짐
  5. 콜백 함수
    . 이벤트 루프가 스택이 빈 것을 확인
    . 큐에서 콜백 함수를 꺼내 스택에 추가, 실행(Second 출력)
    . 끝, 스택에서 빠짐
profile
점점 더 좋아지고 있습니다

0개의 댓글