마이크로태스크
마이크로태스크
프로미스 핸들러는 항상 비동기적으로 실행된다..then().catch().finally()
와 같은 함수 뒤에 적혀 있는 코드가 있다면 뒤에 적혀 있는 코드가 항상 먼저 실행괴고 그 다음 실행된다.
1 | let promise = Promise.resolve(); |
마이크로태스크 큐
비동기 작업을 위한 큐가 있다. ECMA에서는 PromiseJobs
라고 부른다. V8 엔진에서는 이를 마이크로테스크 큐
라고 부른다.
- FIFO 정책을 따른다.
- 실행될 코드가 전혀 없을 때 마이크로테스크 큐에 작업이 실행된다.
.then().catch().fianlly()
는 항상 비동기적으로 실행 된다. 이 작업들은 모두 마이크로테스크 큐에 담기게 되고, 현제 실행될 코드가 없고 이전에 먼저 큐에 담겨진 코드가 모두 실행된 이후에 해당 작업이 실행된다.
처리되지 못한 거부
처리되지 못한 거부는 마이크로태스크 큐 끝에서 프라미스 에러가 처리되지 못할 때 발생한다.
정상적인 경우 .catch()
를 호출해서 에러를 처리하지만 그렇지 못한 경우 엔진은 마이크로태스크 큐가 빈 이후에 unhandlerejection
이벤드를 트리거 한다.
1 | let promise = Promise.reject(new Error("프라미스 실패!")); |
그런데 만약 setTimout()
을 사용하여 에러를 나중에 처리하면
1 | let promise = Promise.reject(new Error("프라미스 실패!")); |
프라미스 실패가 먼저, 잡았다가 나중에 출력되는 것을 볼 수 있다.
unhandlerejection
은 마이크로테스크 큐에 모든 작업이 완료 되면 트리거 된다. 엔진은 프라미스를 검사하고 하나라도 거부 상태이면 핸들러를 트리거 한다..catch()
역시 트리거 된다. 다만 .catch()
는 unhandledrejection
이 발생한 이후에 트리거 된다.