이벤트 루프
먼저 이벤트 루프 가 중요한 개념인 이유를 알아야한다고 생각합니다.
자바스크립트는 '단일 쓰레드' 기반의 언어입니다. 따라서 자바스크립트로 작성한 코드는 동시에 하나의 작업만 처리가 가능합니다. 하지만 자바스크립트를 통해 개발을 해보았다면, 동시에 여러작업이 처리되는 것을 보실 수 있었을겁니다.
Node.js, Chrome 에서 사용하는 V8(자바스크립트 엔진)은 단일 호출 스택(Call Stack)을 사용하며, 실행 컨텍스트(실행할 코드에 제공할 환경정보들을 모아놓은 객체) 들을 이 호출 스택에 쌓아두었다가 상단에 있는 컨텍스트부터 실행(First in Last out)합니다.
자바스크립트가 '단일 쓰레드' 기반이라는 말은 맞지만, 실제 자바스크립트가 실행되는 환경(Node.js, Chrome)에서는 주로 여러개의 쓰레드가 사용됩니다. 이러한 쓰레드들이 단일 쓰레드를 사용하는 자바스크립트 엔진과 상호 연동하기 위해 사용하는 장치가 바로 이벤트 루프 입니다.
Run-to-Completion
자바스크립트의 함수는 Run-to-Completion 방식으로 실행됩니다.
이는 쉽게말해 하나의 함수가 실행되면, 그 함수의 실행이 끝날때까지 다른 작업이 일어나지 못하는 것을 이야기합니다.
Web Apis
웹에서 여러 유용한 작업을 수행할 수 있도록 하는 다양한 API들 입니다.
일반적으로 자바스크립트 코드를 통해 접근할 수 있으며, 대표적인 예로 DOM Events
, AJAX
, Timer
등이 있습니다.
예시
이벤트 루프에 대해 알아보기 전에 예시를 먼저 봐보려합니다.
console.log("Hi!");
setTimeout(function timeout() {
console.log("Click the button!");
}, 5000);
console.log("Welcome to loupe.");
(GIF가 동작하지 않는다면,http://latentflip.com/loupe/로 이동하여 볼 수 있습니다.)
위의 예제에서 timeout
이 Callback Queue
를 거쳐 실행되는 것을 볼 수 있습니다.
앞선 예제의 실행 흐름을 보면 우선 console.log('Hi');
가 실행되고 setTimeout
안의 함수는 Web Apis
영역에서 5000
ms 의 시간을 보냅니다. timeout
함수가 5000
ms 의 사긴을 보내는 동안 console.log("Welcome to loupe.")
가 실행되게 되고 그 뒤 5000
ms 의 시간을 보내고 Callback Queue
에서 대기하고 있던 timeout
이 실행됩니다.
놀랍게도 setTimeout
을 0
ms 로 바꾸더라도 실행순서는 바뀌지 않습니다. 이는 setTimeout
이 백그라운드와 Callback Queue를 거쳐 4
ms 의 지연시간을 가지고 있기 때문입니다.
Event Loop
Event Loop는 Call Stack과 Callback Queue의 상태를 체크하여, Call Stack이 비게되면, Callback Queue의 첫 번째 콜백을 Call Stack으로 밀어 넣습니다.
Promise와 Event Loop
Promise는 마이크로 태스크(Micro task)를 사용하기 때문에, 일반 태스크보다 더 높은 우선순위를 갖게 됩니다.
setTimeout(function() { // (A)
console.log('A');
}, 0);
Promise.resolve().then(function() { // (B)
console.log('B');
}).then(function() { // (C)
console.log('C');
});
Promise도 비동기 처리여서 setTimeout
의 함수와 함께 Callback Queue 에 담긴다고 생각하여 결과가 A → B → C 라고 생각할 수 있지만, 결과는 B → C → A 가 출력됩니다. 이는 앞서 이야기했던 것과 같이 Promise는 마이크로 태스크를 사용하기 때문입니다. 따라서 B와 C를 출력하는 함수는 마이크로 태스크 큐에 따로 담기고 Event Loop는 마이크로 태스크 큐에 담긴 콜백함수를 먼저 실행하게 됩니다.
참고자료
'Language > JavaScript' 카테고리의 다른 글
const, let 호이스팅 알아보기 (0) | 2021.03.17 |
---|---|
Promise와 jQuery Deferred Object (0) | 2020.07.24 |
자바스크립트 Array (배열) (0) | 2019.09.18 |
자바스크립트 고차함수 (0) | 2019.08.27 |
자바스크립트 클로저 (0) | 2019.08.08 |