프로필사진
움짤로 보는 자바스크립트 동작 원리(1) - Event Loop

2020. 5. 14. 11:54🔴 FE/JavaScript

300x250

원문 (영어) : https://dev.to/lydiahallie/javascript-visualized-event-loop-3dif
저자 : Lydia Hallie

👩🏻‍💻Thanks to Lydia for this amazing article about Javascript!


자바스크립트는 단일 쓰레드로 구성되어있다 = 한 번에 하나의 일을 수행하는 것!
만약 하나의 일이 30초가 걸린다면?
우리는 30초를 기다려야하는 상황인 것이다
(자바스크립트는 기본적으로 브라우저의 메인 쓰레드에서 돌아가기 때문에 모든 UI가 막히게 된다)

다행히도, 브라우저는 자바스크립트 엔진 자체가 제공하지 않는 몇 가지 기능을 제공하는데
바로 'Web API'이다.
Web API에는 DOM API, setTimeout, HTTP request 등이 포함되어 있다.
이것들이 우리가 async한 (막히지 않는) 개발을 할 수 있도록 도와준다.


우리가 한 함수를 호출하면, 이것은 'call stack'이라는 곳에 추가된다.
call stack은 자바스크립트 엔진의 일부분으로써, 명확히 따지면 브라우저가 아니다.
이는 하나의 스택인데, 즉 '선입후출'로 실행된다.
따라서 우리가 호출한 함수가 값을 리턴하면, 그 함수는 스택에서 빠져나오게 된다.

위 움짤에서의 'respond()' 함수는 setTimeout 함수를 리턴한다. 
setTimeout은 Web API가 제공하는데, 메인 쓰레드를 막지 않고 일을 수행하도록 해준다.
그다음, setTimeout의 콜백함수인 ()=> {return 'Hey'}는 Web API에 추가된다.
그동안 setTimeout()와 respond()은 스택에서 빠져나오고 값을 리턴한다.

Web API 안에서는 우리가 setTimeout()에서 2번째 인자로 넣은 1000ms동안 타이머가 돌아간다.
해당 콜백은 바로 call stack으로 보내지지 않고, 대신 queue라는 공간에 넣어진다.

이 부분이 약간 헷갈릴 수 있는데, 콜백함수가 1000ms 이후에 callstack에 추가되고 값을 리턴한다는 뜻이 아니다!
그것은 1000ms이후에 단순히 queue에 넣어지는 것이고,
해당 함수는 자신의 차례가 올 때까지 기다려야 한다.


이제 대망의 event loop이 나올 차례다! 
event loop은 queue를 call stack과 연결해주는 역할을 한다.
만약 call stack이 비어지면 (= 호출되었던 모든 함수들이 그들의 값을 리턴하고 스택에서 pop! 해서 나오면),
queue에 저장되어 있던 첫번째 항목이 call stack에 추가된다.
이러한 상황에서는 다른 함수들이 호출되지 않는데,
즉 콜백 함수가 queue에서 첫 번째 항목일 때 call stack이 비어졌다는 뜻이다.

콜백 함수가 call stack에 추가되고 👉🏻호출된 다음 👉🏻값을 리턴하고 👉🏻스택에서 빠져나온다.


const foo = () => console.log("First");
const bar = () => setTimeout(() => console.log("Second"), 500);
const baz = () => console.log("Third");

bar();
foo();
baz();

콘솔에 찍어보면 어떻게 나올까?

브라우저에서 위에 코드를 돌리면 이런 식으로 돌아간다 :

1. bar()을 호출함 -> setTimeout 함수를 리턴한다.

2. setTimeout()의 콜백은 Web API에 추가되고, setTimeout()과 bar()이 call stack에서 빠져나온다.

3. 타이머가 돌아가기 시작하고, 그동안 foo()가 호출되고 "First"라고 로그에 찍힌다.
foo()는 undefined를 리턴하고, baz()가 호출되고, 콜백이 queue에 추가된다.

4. baz()가 "Third"라고 로그를 찍는다. baz()가 리턴된 후, event loopt은 call stack이 빈 것을 확인한다.
그다음 콜백이 call stack에 추가된다.

5. 콜백이 "Second"라고 로그를 찍는다.

300x250