November 18, 2021

프라미스 핸들러 .then/catch/finally는 항상 비동기적으로 실행됩니다.

프라미스가 즉시 이행되더라도 .then/catch/finally 아래에 있는 코드는 이 핸들러들이 실행되기 전에 실행됩니다.

예시:

let promise = Promise.resolve();

promise.then(() => alert("프라미스 성공!"));

alert("코드 종료"); // 이 얼럿 창이 가장 먼저 나타납니다.

예시를 실행하면 '코드 종료’가 먼저, '프라미스 성공!'이 나중에 출력되는 것을 볼 수 있습니다.

프라미스는 즉시 이행상태가 되었는데도 말이죠. 뭔가 이상하네요.

왜 .then이 나중에 트리거 되었을까요? 그 이유에 대해 알아봅시다.

마이크로태스크 큐

비동기 작업을 처리하려면 적절한 관리가 필요합니다. 이를 위해 ECMA에선 PromiseJobs라는 내부 큐(internal queue)를 명시합니다. V8 엔진에선 이를 '마이크로태스크 큐(microtask queue)'라고 부르기 때문에 이 용어가 좀 더 선호됩니다.

요약

모든 프라미스 동작은 ‘마이크로태스크 큐’(ES8 용어)라 불리는 내부 ‘프라미스 잡(promise job)’ 큐에 들어가서 처리되기 때문에 프라미스 핸들링은 항상 비동기로 처리됩니다.

따라서 .then/catch/finally 핸들러는 항상 현재 코드가 종료되고 난 후에 호출됩니다.

어떤 코드 조각을 .then/catch/finally가 호출된 이후에 실행하고 싶다면 .then을 체인에 추가하고 이 안에 코드 조각을 넣으면 됩니다.

브라우저와 Node.js를 포함한 대부분의 자바스크립트 엔진에선, 마이크로태스크가 '이벤트 루프(event loop)'와 '매크로태스크(macrotask)'와 깊은 연관 관계를 맺습니다. 이 둘은 프라미스와는 직접적인 연관성이 없기 때문에, 이벤트 루프와 매크로·마이크로태스크에서 따로 다루도록 하겠습니다.