Skip to content

자바스크립트 비동기 처리 (2/2)

Share on facebook
Facebook
Share on twitter
Twitter
Share on linkedin
LinkedIn

들어가기 전에

이전 글 ‘자바스크립트 비동기 처리 (1/2)‘에서 자바스크립트 엔진과 비동기 처리를 위한 런타임 환경에 대해서 알아보았다.

이번 글에서는 자바스크립트에서 비동기 처리를 가능하게 해주는 태스크 큐 (task queue)와 이벤트 루프 (event loop)에 대해 알아보겠다.

태스크 큐 (Task queue)

태스크 큐는 사용하는 API에 따라서 (매크로) 태스크 큐(macrotask queue)와 마이크로태스크 큐(microtask queue)로 구분된다.

(매크로) 태스크 큐 (Macrotask queue)

  • 사용하는 API : setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O, UI rendering

마이크로태스크 큐 (Microtask queue)

: 태스크 큐보다 높은 우선순위를 갖고 먼저 처리된다.

  • 사용하는 API : process.nextTick, Promise, queueMicrotask(f), MutationObserver

이벤트 루프 (Event loop)

이벤트 루프는 지속적으로 콜 스택(call stack)과 태스트 큐(콜백 큐, callback queue)를 모니터링하여 콜 스택이 비어있다면 태스트 큐에 있는 콜백 함수를 콜 스택으로 옮겨 처리한다.

또한, 이벤트 루프는 마이크로태스트 큐에 있는 모든 태스크를 처리한 다음, 매크로태스크에 있는 큐를 처리한다.

이벤트 루프 동작 방식

1. 콜 스택이 비어있으면 마이크로태스크 큐에 적재된 작업이 있는지 확인

2. 마이크로태스크 큐에 적재된 작업을 콜 스택으로 순차적으로 옮겨 실행하고 비어있으면 매크로태스크 큐에 적재된 작업이 있는지 확인

3. 매크로태스크 큐에 적재된 작업을 콜 스택으로 옮겨 실행

4. 위의 과정을 반복

다음 코드를 통해 (매크로) 태스크 큐와 마이크로태스크 큐에 적재된 작업이 어떻게 처리되는지 확인해보자.

console.log('[1]');
setTimeout(function () {console.log("[2]")}, 0);

const p = Promise.resolve();
p.then(function() {
    setTimeout(function() {
        console.log('[3]')
        setTimeout(function() {console.log("[4]")}, 0);
        p.then(() => console.log('[5]'));
    }, 0);
    console.log("[6]");
});

console.log("[7]")

1. 이벤트 루프가 로드된 스크립트를 실행시키면 처음 console.log('[1]')를 콜 스택으로 옮기고 코드가 실행된다.

2. console.log('[1]') 함수가 종료되면 콜 스택에서 제거되고 setTimeout()이 콜 스택으로 이동해 Web API에서 타이머를 수행한 후 태스크 큐에 적재된다.

3. Promise.resolve() 함수가 콜 스택으로 적재되고 콜백 함수인 then이 마이크로태스크 큐에 적재된다.

4. console.log('[7]')이 콜 스택에 적재되고 코드가 실행된다.

5. 이벤트 루프는 우선순위가 높은 마이크로태스크 큐에 있는 then을 콜 스택으로 적재해 then 안에 있는 setTimeout을 처리해 태스크 큐에 적재하고 console.log는 콜 스택으로 적재한다.

6. 태스크 큐에 있는 첫번째 timer를 콜 스택에 적재하고 console.log('[2]') 가 수행된다.

7. console.log('[2]') 수행 후 콜 스택이 전부 비워지면 이벤트 루프는 태스크 큐에 있는 timer를 콜 스택에 적재해서 console.log('[3]'), setTimeout, then이 실행된다.

8. console.log('[3]')이 출력되고 콜 스택이 전부 비워지면 이벤트 루프는 우선순위가 높은 마이크로태스크 큐에 있는 then을 콜 스택에 적재하고 console.log('[5]')이 실행된다.

9. console.log('[5]'이 출력되고 콜 스택이 전부 비워지면 태스크 큐에 있는 timer를 콜 스택에 적재해 console.log('[4]')이 실행된다.

결론

자바스크립트 구현 시 매크로태스크, 마이크로태스크에 따라서 처리되는 우선순위가 다르기 때문에 둘의 작동방식을 이해하고 사용하는 것은 중요하다. 또한, 이벤트 루프는 자바스크립트 런타임 환경이기 때문에 사용하는 런타임에 따라서 상세 구현이 다르다. (Node.js에서 비동기 처리를 담당하는 libuv 라이브러리는 HTML 스펙을 따르지 않기 때문에 상세 구현이 다르다.) 본 글에서는 HTML 스펙에 대한 내용만 다루었기 때문에 나중에 기회가 된다면 Node.js의 libuv에 대해서도 정리해 볼 계획이다.

Share your blockchain-related digital insights with your friends

Share on facebook
Facebook
Share on twitter
Twitter
Share on linkedin
LinkedIn

Get more insights

‘EIP-1559’란 무엇인가?

새로 적용된 EIP-1559. 이더리움 네트워크에 어떤 변화를 가져오고 있는지에 대해 알아보자.

2021 Luniverse Annual Report 최초 공개

루니버스의 2021년 최신 비공개 데이터 및 TOP5 블록체인 디앱을 지금 바로 확인해보세요.

가상자산(암호화폐, 비트코인)의 내재가치 및 금융 혁신의 가능성

들어가며 가상자산은 Dapp내 서비스 이용, 개인 및 기관투자자의 투자 포트폴리오 다각화, NFT 마켓플레이스에서의 제품 구입 그리고 e-커머스시장에서의 결제 등 사용처가 다양하다. 본 글에서는 하기와 같은 세 가지 분야와 각 분야의

[유니스왑] 교환비율 조정 매커니즘은 어떻게 작동되는가?

유니스왑 서비스 소개 및 기본적인 작동원리에 대해 소개하고자 한다.