Event Loop

성훈·2021년 7월 28일
0

OiMW

목록 보기
7/12
post-thumbnail

Event Loop

자바스크립트는 코드를 실행할때 Stack에 함수를 쌓고 연계된 다른 함수가 있으면 그 함수도 Stack에 쌓는 식으로 코드를 실행하다가 쌓는 역순으로 스택에서 빼내며 결과를 반환해 나간다.

이때 setTimeout 같은 Web APIStack이 아닌 Web API(s)로 빼내 설정한 타이머를 돌린다.
그리고 지정된 시간이 되면 이 타이머의 콜백 함수를 바로 Stack에 쌓아 실행시키는 것이 아닌 Task Queue라는 곳에 보냈다가 Stack이 빌때, Event Loop를 통해 Stack으로 이동하고 해당 콜백 함수가 실행된다.

여기서 이 이벤트 루프는 단순히 Task Queue에 있는 것들을 Stack이 비었을때 Stack으로 보낼뿐인 아주 간단한 작업을 하는 기능인데 이 이벤트 루프가 실행되는 조건인 Stack이 비었을때 Task Queue에서 Stack으로 이동시켜 실행한다는 점 때문에 원하지 않는 결과가 발생할 수 있다.

예를 들어

const logging = () => {
  console.log('a');
  setTimeout(()=>{
      console.log('b');
  }, 0);
  console.log('c');
}

logging(); // 'a', 'c', 'b' 순으로 로그가 남는다. 

위와 같은 상황에서 바로 콘솔로그 사이에 있는 setTimeout에서 설정한 시간이 0밀리초니까 abc 순서대로 로그가 남을 것 같지만 전술한 것 처럼 setTimeout은 웹API에서 Task Queue로 보내는 시간만 정해주고 이벤트 루프가 Stack으로 보내 실행시키는 역할을 하므로 로그는 acb순으로 남는다.

또 다른 경우로 setTimeout의 두번재 인자로 1000밀리초를 주었을때, 어떠한 경우에도 1초 후에 콜백 함수가 실행이 되어야 할 것 같지만 재귀나 데이터를 받아온다던가 하는 것의 이유로 콜스택이 비워지지 않는다면 1초는 무슨 해당 함수가 종료되지 않는 한 콜백함수는 실행되지 않을 것이다.

Browser Blocking

여기까지 왔으면 이벤트 루프를 막지말라는 뜻이 무엇인지 알 수 있을 것이다.
조금만 더 나아가서 브라우저는 16.6밀리초, 1초에 60번씩 repainting 하는데, 이 repainting 은 이벤트 루프를 통해서 실행된다.

다만 Web API와 차이repainting이 Queue에 있다면 이벤트 루프는 Task Queue에 대기중인 콜백 함수가 있더라도repainting가장 먼저 Stack으로 보내 실행시킨다.

덕분에 Task Queue가 범람하든 말든 렌더는 정상적으로 이루어지지만 문제는 Stack에서 어떤 놈이 버티고 있을때이다.

Stack이 비워져야 이벤트 루프가 작동을 할텐데 이 조건이 충족되지 않으니 렌더를 못하게 되고 결과적으로 브라우저 화면이 멈추게 되는 것이다.

고로 누군가에게 이벤트 루프를 막지 말라는 조언을 들었다면 지금 콜 스택에 누가 자리잡고 안비켜주는지 확인 하라는 뜻과 비슷하게 생각하면 될 듯 하다.

Reference

https://www.youtube.com/watch?v=8aGhZQkoFbQ

profile
어떻게 이걸 풀어낼 수 있을까

0개의 댓글