[Javascript] Event Loop

BBinss·2020년 12월 22일
0
post-thumbnail

javascript event loop

javascript 언어 자체적으로 멀티 스레드 지원이 되지 않는 것인데 어떻게 여러 요청들을 동시에 처리하는 동시성을 가지는 것일까?

@ 조금 부연 설명을 하자면 nodejs의 cluster 환경을 사용하면 application을 병렬적으로 사용하는 것이 가능하다.
하지만 하나의 프로세스 위에 싱글 스레드로 동작하는 application을 병렬적으로 사용하는 방식이고
event loop의 개념은 application 코드 자체의 동작에 관련된 부분이다.

그래서 event loop라는 개념을 알아야 하는데, 사실 ECMAScript 언어 스펙 자체에는 event loop가 존재하지 않는다.
브라우저 혹은 nodeJs와 같은 javascript를 구동하는 엔진 환경에서 event loop를 담당하는 것이다.

Call stack, Task Queue (Callback queue).

먼저 명칭에 대해서 살펴보면

  • javascript 엔진의 call stack에는 현재 실행 중인 함수가 존재한다.
  • task queue 혹은 callback queue는 특정 요청 이후 비동기적으로 실행될 callback 함수들이 차례대로 입력된다.

단일 호출 스택, run to completion.

  • call stack에는 하나의 호출 스택만이 존재한다.
  • run to completion 이란 하나의 함수가 실행이 끝나야지만 다른 함수가 실행이 가능하다.
    즉 call stack에는 하나의 호출 스택만이 존재하고 하나의 함수가 실행이 완료되기 전까지는 다른 함수는 실행되지 못한다.

동작 방식

const AAA = () => {
  for (let i = 0; i < 10000; i++) {}

  console.log('AAA');
};

setTimeout(() => {
  console.log('BBB');
}, 50);

AAA();

그럼 위의 코드를 예로 동작 방식에 대해서 살펴보면,
1. 코드를 차례로 실행하면서 현재 실행할 함수인 setTimeout을 call stack에 입력 후 실행한다.
2. 실행 후 call stack이 비워진다. 단일 호출 스택이므로 항상 하나의 호출 스택을 유지한다.
3. setTimeout으로 전달된 콜백 함수는 WebAPIs의 timer 함수를 통해 50ms 이후 callback queue로 입력 이 된다.
4. event loop는 지속적으로 현재 call stack에 실행 중인 task가 있는지, task queue에 실행 대기중인 task가 있는지를 체크한다.
만약 call stack에 실행 중 task가 없고 task queue에 실행 대기 중인 task가 있다면 첫 번째 task를 call stack으로 추가한다.

이 코드에서 중요한 점은 setTimeout() 함수가 먼저 실행되고 50ms 이후에 전달 콜백 함수가 task queue에서 실행을 대기하게 될텐데,
AAA() 함수에서 for문이 아무리 오랜시간이 걸리게 되더라도 setTimeout() 전달 콜백 함수가 먼저 실행되는 일은 없다.

/* 실행 결과 */
// AAA
// BBB

setTimeout이 아닌 XMLHttpRequest와 같은 비동기 함수들도 마찬가지다.
http 요청 후 결과가 왔을 때 해당 콜백 함수를 task queue에 추가해 준다. 그러면 현재 실행중인 call stack이 없다면 event loop는 task queue에서 첫 번째 함수를 call stack에 추가하면서 실행해주게 된다.

결론

정리하면, javascript는 event loop를 통해서 비동기 방식의 동시성을 지원한다.
비동기 함수 호출시 특정 API에서 처리한 후 task queue에 차례로 추가해 준다. 그럼 event loop는 주기적으로 call stack가 비워질 때마다 해당 task를 추가하여 실행시킨다.

Non-Blocking IO의 형태이기도 하며, 이런 형태를 통해 함수를 일단 차례로 다 실행할 뿐이다.
이후 특정 API를 통해 처리되는 대로 task queue에 입력이 되면 event loop가 차례대로 queue에서 실행 함수들을 실행하고 call stack에 추가되는 역할을 한다.

이를 통해 여러 http 요청을 하거나 특정 event listener를 통해 다중 이벤트를 처리하는 등의 동시성을 지원하게 된다.

참고

profile
궁빈

0개의 댓글