이벤트루프는 자바스크립트가 비동기로 작동할 수 있게 만들어주는 도구입니다.
(저는 도구(: 어떤 일을 할 때 이용하는 장치)라고 생각합니다.)
자바스크립트는 싱글 스레드 언어이지만
ajax 요청이나 setTimeout같은 비동기 처리가 가능합니다.
여기서 싱글 스레드란 하나의 콜 스텍을 가지고
하나의 프로그램이 동시에 하나의 코드만 실행할 수 있다는 뜻입니다.
왜냐하면 자바스크립트 런타임 환경인 브라우저에서
webAPI가 비동기 함수를 처리하기 때문입니다.
webAPI는 각 API 마다 스레드들이 할당되어있고
이들이 모여 멀티 스레드로 이루어져 있습니다.
webAPI가 비동기 함수를 처리하고
여기서 바로 이벤트 루프가 처리된 비동기 함수를 콜 스택에 전달해주어
콜 스택에서 처리된 비동기 함수가 실행됩니다.
다음과 같은 setTimeout 콜백함수를 실행시켜보겠습니다.
console.log("Hi!");
setTimeout(function timeout() {
console.log("Click the button!");
}, 5000);
console.log("Welcome to loupe.");
setTimeout은 자바스크립트 엔진인 V8에게는 없는 함수입니다.
웹 브라우저에서 webAPI가 대신 실행해 줄 수 있습니다.
1. console.log("Hi"!) 를 먼저 실행시키고
2. timeout()은 webApis로 넘긴뒤
3. console.log("Welcome to loupe.") 를 실행시키고
4. 5초뒤 처리가 완료된 timeout()을 web API에서 Callback Queue로 넘겨줍니다.
5. 이벤트루프는 Call Stack을 주시하고 있다가 빈 것을 확인하면
Callback Queue의 첫번째 콜백을 Call Stack에 쌓아 실행시킵니다.
여기서 의문이 드는 점은
만약에 0초후에 실행되는 setTimeout을 실행시키면 바로 실행이 될까요 ?
결론부터 말하자면 아닙니다.
어찌되었건 setTimeout은 자바스크립트 엔진이 처리할 수 없는 함수로
Web API로 넘겨지게 됩니다.
이렇게 넘겨진 함수는 곧바로 처리되어 Callback Queue에서 대기하다가
Call Stack이 비워진것을 이벤트 루프가 확인한 후에야
Call Stack으로 이동되어 실행될 수 있습니다.
또 다른 의문으로는 1초 후에 실행되는 setTimeout을 여러번 실행시키면
모두 1초뒤에 동시에 실행될까요 ?
이번 결론도 아닙니다.
아래와 같은 코드를 실행해 보겠습니다.
setTimeout(function timeout1() {
console.log("Click the button1!");
}, 1000);
setTimeout(function timeout2() {
console.log("Click the button2!");
}, 1000);
setTimeout(function timeout3() {
console.log("Click the button3!");
}, 1000);
setTimeout(function timeout4() {
console.log("Click the button4!");
}, 1000);
자바스크립스는 코드를 순서대로 만나게되고
순서대로 만난 timeout 함수들을 차례대로 WebAPI가 처리해서
순서대로 Callback Queue에 대기하게 됩니다.
Callback Queue는 가장 첫번째에 있는 콜백을 처리하므로
timeout1,2,3,4 순서대로 실행이됩니다.
결론
말로만 듣던 (그동안 이해가 안갔던) 이벤트 루프의 동작 방식을 이해하고 나니 시원합니다.
그림으로 이해해야 쉬운데 소스를 만드는게 쉽지 않습니다.
미래의 이 글을 읽을 나의 이해를 돕기 위해 아래와 같은 레퍼런스를 남깁니다.
특히 두번째 링크는 첫번째 링크의 강연자가 만든 이벤트 루프를 이해하기 쉽게 시각화 시킨 좋은 사이트입니다.
https://www.youtube.com/watch?v=8aGhZQkoFbQ
http://latentflip.com/loupe/?code=JC5vbignYnV0dG9uJywgJ2NsaWNrJywgZnVuY3Rpb24gb25DbGljaygpIHsKICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gdGltZXIoKSB7CiAgICAgICAgY29uc29sZS5sb2coJ1lvdSBjbGlja2VkIHRoZSBidXR0b24hJyk7ICAgIAogICAgfSwgMjAwMCk7Cn0pOwoKY29uc29sZS5sb2coIkhpISIpOwoKc2V0VGltZW91dChmdW5jdGlvbiB0aW1lb3V0KCkgewogICAgY29uc29sZS5sb2coIkNsaWNrIHRoZSBidXR0b24hIik7Cn0sIDUwMDApOwoKY29uc29sZS5sb2coIldlbGNvbWUgdG8gbG91cGUuIik7%21%21%21PGJ1dHRvbj5DbGljayBtZSE8L2J1dHRvbj4%3D
latentflip.com
'JavaScript' 카테고리의 다른 글
This (2) | 2023.09.12 |
---|---|
실행컨텍스트 (Execution Context) (0) | 2023.09.04 |
모듈(Module) (0) | 2023.09.01 |
클로저 (Closure) (0) | 2023.08.30 |
스코프(scope) (2) | 2023.08.28 |