✨♻️ JavaScript Visualized: Event Loop를 번역한 글입니다.
오! 이벤트 루프(Event loop). 모든 자바스크립트 개발자들이 다루고 있는 것 중 하나지만, 처음에는 조금 혼란스러울 수 있다. 나는 시각적인 학습자(visual learner)라서 시각적인 방법(저화질의 GIF들)을 통해서 설명해주려 한다. (왜냐하면 2019년인데 Gifs는 여전히 픽셀화 되어있고 흐릿하기 때문이다.)
일단 처음으로, 이벤트루프는 무엇이고 왜 신경써야하는지 알아보자
자바스크립트는 싱글스레드이다. 오직 한 번에 한 작업만 실행한다. 대게는 별 상관없다, 하지만 30초가 걸리는 작업을 실행시킨다고 생각해봐라.... 음... 너가 30초를 기다리는 동안, 어떤 일도 일어날 수 없다.(자바스크립트는 기본적으로 브라우저의 메인스레드에서 실행된다, 즉 완벽하게 UI는 멈춘다.) 😬 2019년이다, 아무도 느리고 반응이 느린 웹사이트를 원하지 않는다.
운좋게도, 브러우저는 자바스크립트 엔진자체에서 제공하지 않는 몇 가지 기능들을 제공한다. 바로 Web API다. Web API는 DOM API, setTimout, HTTP request, 등등을 포함한다. 이것들은 우리에게 비동기적이고 논-블록킹 동작들을 만들 수 있게 해준다.
함수를 호출하면 콜 스택(Call Stack)이 추가된다. 콜 스택은 JS 엔진의 일부이며 브라우저마다 다르다. 이건 스택입니다. 즉, 처음 들어온 것이 마지막에 나갑니다.(First In Last Out)(팬케이크 더미와 같습니다) 함수가 값을 반환하면 스택에서 팝(Pop)됩니다. 👋
이 respond
함수는 setTimeout
을 리턴한다. setTimeout
은 Web API에 의해 제공된다. 즉, 메인 스레드를 차단하지 않고 작업을 지연시킬 수 있다. setTimeout
함수를 전달하는 콜백(Callback) 함수, 화살표 함수 () => { return 'Hey'}
는 웹 API에 추가된다. 그 동안 setTimeout
함수와 응답 함수가 스택에서 팝되어 둘 다 값을 반환했다!
웹 API에선, 우리가 제공한 1000ms란 두번쨰 인자만큼 계속 타이머가 돌아간다. 콜백은 즉시 콜 스택에 추가되지 않는다. 대신에 큐에 넘겨진다.
이 부분은 혼란스럽다. 1000ms 후에 콜백 함수가 콜 스택(값을 반환하는)에 추가되지 않는다. 단순하게 1000ms 뒤에는 큐에 추가된다. 하지만 큐에는, 함수가 차례(turn)를 기다려야 한다.
지금 이 부분이 우리가 기다리던 부분, 바로 이벤트루프가 유일한 작업을 수행할 시간이다. 큐와 call stack을 연결하라. 만약 콜 스택이 비워져서, 이전에 호출된 모든 함수들이 값을 리턴하고 스택에서 나갔다면, 큐에서 첫 번째 항목이 콜 스택에 추가됩니다. 이 경우엔 다른 함수들이 호출되지 않으며, 콜백 함수가 큐의 첫 번째 함수일 때쯤에 콜백 함수가 비어있다는 것을 의미한다.
콜백은 콜 스택에 추가되어 호출되고, 값을 반환한 다음, 스택에서 나가게(popped)된다.
글을 읽는 것은 재밌지만, 완벽하게 익숙해지려면 계속해서 실제로 어떻게 작동하는지를 알아야한다. 콘솔에 어떤 로그가 나타나는지 다음의 예제를 실행시켜보자.
const foo = () => console.log("First");
const bar = () => setTimeout(() => console.log("Second"), 500);
const baz = () => console.log("Third");
bar();
foo();
baz();
이해가 되었나? 우리가 이 코드를 브라우저에서 실행시켰을 때 어떤 일이 일어났는지 한번 빠르게 살펴보자.
console.log()를 기록한다로 번역함
bar
가 호출되었다. bar
는 setTimeout
함수를 반환하였다.setTimeout
에 넘긴 콜백함수는 Web API에 추가되었다, setTimeout
함수와 bar
는 콜 스택에서 나가졌다.(popped off)foo
는 호출되고 First
가 기록(log)된다. foo
는 (undefined)를 반환한다. baz
는 호출되고, 콜백은 큐에 추가된다.baz
는 Third
를 기록한다. 이벤트 루프는 콜백이 비어진 다음에 baz
를 반환한다. 그 후에 콜백은 콜 스택에 추가된다.Second
를 기록한다.이 글이 이벤트 루프에 대해서 좀 더 편한하게 해줬으면 바란다! 아직 혼란스럽다고해도 걱정마라, 올바른 용어를 효율적으로 구글링하고 스택오버플로우에 질문하기 위해서, 특정한 에러들과 동작들이 어디에서 발생했는지를 이해하는 것이 제일 중요하다. 질문이 있으면 자유롭게 물어보기 바란다.