Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

Murpin Tech'blog

웹 브라우저에서의 이벤트 루프와 비동기 이해 : 이벤트 큐(2) 본문

FrontEnd/개인공부

웹 브라우저에서의 이벤트 루프와 비동기 이해 : 이벤트 큐(2)

Murpin 2022. 8. 13. 16:08

안녕하세요 저번에 포스팅에서 올렸던 이벤트루프와 비동기 이해에서 말했던 것처럼 Event Queue에 대해 끄적여 보겠습니다.
일단 먼저 Event Queue에 대해 여러분들은 어떻게 처음 알게 되었나요?저의 경우에는
전설의 JS Event Loop 강의에서 처음 알게 되었습니다.
혹시 보지 않으신 본과 보신 분들은 꼭 봐주시길 바랍니다.

여기서부터는 우리는 event loop의 존재와 event를 저장하는 queue가 존재한다는 것을 알고 있다는 전제로 설명하겠습니다. 위의 강의를 보셨다면 이벤트 큐가 하나로만 설명되었습니다.
하지만! 그렇지 않습니다. 이벤트 큐는 하나가 아닌 총 3개로 이루어져있습니다. ㄴㅇㄱ
한번 쭉 나열을 해보면
* microTaskQueue(Job Queue)
* animationFrames(Render Queue)
* macroTaskQueue(Event Queue)

microTaskQueue(Job Queue)

해당 큐를 가장 먼저 쓴 이유가 있습니다.
바로 이벤트 큐 중 *우선순위*가 가장 높습니다. microTaskQueue가 처리하는 타입은 Promise입니다.
그래서 Promise와 다른 비동기 처리(ex. setTimeout, requestAnimationFrame)의 콜백보다 먼저 호출됩니다.
예시를 보면

console.log("start"); 
setTimeout(() => 
           console.log("timeout")); 
Promise.resolve() 
  .then(() => console.log("promise"));
console.log("end"); 
//결과값 
//start 
//end 
//promise 
//timeout

Promise의 콜백이 microTaskQueue에 등록되는 시점은 Promise로 resolve 되는 시점입니다.

하나의 정보를 적어보자면 microTaskqueue에 만약 비워지지 않는다면 requestAnimationFrame이 실행되지 않는데
이 비동기 처리는 렌더링 과정 이전에 microTaskQueue가 실행되는 시점은 렌더링이 되기 이전이며,
해당 큐가 비워지기 전까지는 해당 큐의 콜백을 계속해서 시전하게 됩니다.

animationFrames(Render Queue)

자, 그럼 위의 설명 그대로 보았을 때 왜 이게 우선순위가 두번째인지 이해가 될 것입니다.
이 부분은 web api를 관리하는 것이 아닌 렌더러 쓰레드에 의해 등록되어지는 큐입니다animationFramse에서는 requestAnimationFrams>RenderTree>Layout/Paint를 호출하여 일련의 과정을 수행합니다.
한마디로 우리가 자바스크립트로 스타일을 수정하거나 애니메이션을 수행하게 된다면 animationFrame을 통해 화면을 업데이트 합니다.## macroTaskQueue(Event Queue)이제 우리가 영상으로 시청했던 해당 큐가 등장했습니다.
해당 큐가 우리가 흔히(?) 알고 있는 이벤트 큐가 보통 이 부분에 해당합니다.
관리하는 요소로는 network(ajax), user event, setTimeout, setInterval등이 있습니다.
macroTaskQueue 의 경우에는 렌더링 이후에 실행됩니다.
만약 macroTaskQueue에 콜백이 남아있다고 해도 microTaskQueue에 콜백이 존재한다면 microTaskQueue가 가장 먼저 시행됩니다.

console.log("script start");    
const timer = setTimeout(function(){        
  console.log("setTimeout1")    
}, 0);    
console.log(timer);    
const timer1 = setTimeout(function (){      
  console.log("setTimeout2");    
}, 0);    
console.log(timer1);    
console.log("script end");

위의 코드의 결과 입니다.

script start
2
3
script end
steTimeout1setTimeout2

setTimeout에 두번째 인자로 0을 넣어서 테스트를 진행하였으니 0초면 바로 수행해야할 것 같지만, 웹 엔진은 해당 코드를 web api>queue>eventloop>callstack의 순서로 실행되기 때문에 바로 실행되지 않는다는 것입니다.

정리

이제 전체적으로 큐를 비교 및 정리해 보겠습니다.
이제 해당 큐의 순서와 렌더링에 따른 큐의 이벤트 처리에 대한 순서가 존재하고 있구나를 이번 포스팅을 하면서 깨닫게 되었습니다.
하나씩 정리하면

  • microTaskQueue는 가장 우선순위가 높은 큐이며, Promise타입의 콜백을 다룬다. 또한, 렌더링 이전에 처리가 이루어진다.
  • animationFrame는 렌더링 쓰레드를 처리하는 큐이다. 해당 내용은 브라우저 RenderTree이전에 이루어진다.
  • macroTaskQueue의 경우 가장 낮은 우선순위의 큐이며, 위 두개의 큐에 콜백이 남아있는 경우, 사라질 때까지 작동하지 않는다.
    다음 포스팅에서는 블로깅을 위해 공부하고 있을 때 궁금해진 내용에 대해 정리해보려고 한다.
    (아래 두가지 저에대한 질문은 스쳐지나가며 본 내용이라 그렇게 중요하지 않거나 잘못된 내용일 수 있습니다!!)
  • 그렇다면 Promise 타입은 저기서 처리하는 async/await은 어떻게 처리하지?*
  • microTaksQueue가 우선순위를 역전하는 예외경우도 있다고??*

'FrontEnd > 개인공부' 카테고리의 다른 글

Git(분산형 버전관리 시스템)이란?  (0) 2022.09.20
Web Storage란?  (0) 2022.09.06
웹 브라우저에서의 이벤트 루프와 비동기 이해(1)  (0) 2022.07.10
What'is DOM?  (0) 2022.04.27