본문 바로가기
Frontend/Javascript

[JS] 이벤트 루프

by jojo 2022. 1. 27.

 

 

 

▷ 동기, 비동기 처리

자바스크립트는 단 하나의 실행 컨텍스트 스택을 가지고 싱글 스레드 방식으로 동작하는데, 이는 한 번에 한가지 일(task)를 처리할 수 있다는 의미이다. 따라서 블로킹(blocking), 즉 특정 태스크를 실행하는 동안 작업이 중단되는 현상이 나타난다. 

// synchronous
function rest(delay) {
  const delayUntil = Date.now() + delay;
  while(Date.now() < delayUntil);
  
  console.log('finished');
}

rest(3*1000)

위 코드를 실행하게 되면 3초 후에 'finished' 라는 메시지를 확인할 수 있다. 이처럼 태스크를 순서대로 하나씩 처리하는 것을 동기(syncronous)처리라고 한다. while문의 조건이 false가 되기까지 걸리는 3초의 시간동안 console.log 메서드는 blocking 현상을 겪는다. 

만약 while을 실행하는 시간이 3초가 아니라 아주 긴 시간이라면, 혹은 작성한 코드 중간에 시간이 오래 소요되는 복잡한 연산이 있다면 뒤에 있는 코드들은 실행되지 못하고 계속 차례를 기다려야 하는 불편한 상황이 생기게 된다. 이러한 문제점을 해결할 수 있는 방법이 비동기(asynchronous) 처리이다.   

 

// asynchronous
function func1() {
  console.log('one')
 }
  
function func2() {
  console.log('two')
}

setTimeout(func1, 3000);
func2();

비동기처리를 수행하는 함수를 비동기 함수라고 하는데, setTimeout은 대표적인 비동기함수이다. 위에서 본 동기함수를 통해 추측할 수 있듯, 정해진 task를 하나하나 처리하는 것이 아니라 현재 task가 종료되지 않더라도 다음 task를 실행하는 처리를 하는 흐름을 비동기 처리라고 한다. 

위 코드에서 setTimeout 함수는 3초의 시간이 흐른뒤에 콜백 함수 func1을 호출한다. setTimeout은 fun2 함수를 블로킹 하지 않기 때문에 콘솔 창에는 func2 함수의 실행값이 먼저 나타나고 3초 후에 func1 함수의 실행값이 나타나게 된다. 

이처럼 비동기 처리는 블로킹이 발생하지 않는 장점을 가진다. 

 

▷ event loop 

이벤트 루프란 task가 있다면 그것을 처리하고 없을 경우에는 잠드는, 자바스크립트 내 루프이다. 

웹브라우저의 내부를 그림으로 표현하면 다음과 같다. 

 

출처: 유튜브 코딩애플

 

 

  • 힙 (heap) : 객체를 저장하는 메모리 공간. 실행 컨텍스트는 힙 안에 있는 정보를 참조한다.
  • 스택 (call stack) : 실행 컨텍스트 스택. 
  • 큐 (task queue) : 비동기 함수의 콜백 함수 또는 이벤트 핸들러가 일시적으로 보관되는 영역. 

이벤트 루프는 콜 스택에 실행중인 실행 컨택스트가 있는지 확인한다. 콜 스택이 비었다면 태스크 큐에 대기중인 함수(콜백 함수, 이벤트 핸들러 등)을 순차적으로 콜 스택으로 이동시킨다. 

function run() {
  console.log('3초 후 실행')
}

console.log('시작')
setTimeout(run, 3000)
console.log('끝')

위 함수를 실행한다고 하자.

1. 전역 컨택스트가 생성되고, 콜 스택에 올라간다.

2. 힙에 run이 선언된다.

3. 콜 스택에 console.log가 푸시되고 콘솔창에 '시작' 을 띄운 후 콜 스택에서 팝된다.

4. setTimeout 함수가 실행되면 콜 스택에 푸시된 후 다음 task가 실행되는 동안 대기실에서 setTimeout의 타이머가 계속 실행되고 있다. 

3. 콜 스택에 console.log가 푸시되고 콘솔창에 '끝' 을 띄운 후 콜 스택에서 팝된다.

4. 전역 코드 실행이 종료되고 이벤트 루프에 의해 콜 스택이 비어있음이 확인되면, 대기실에 있던 콜백함수가 태스크 큐에 등록된다.

5. 태스크 큐에 있던 콜백함수 run이 이벤트 루프에 의해 콜 스택에사 푸시되고 실행된다.

6. run 함수가 종료되고 콜 스택에서 팝된다.

 

실행 화면

 

댓글