You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
예시를 실행하면 `코드 종료`가 먼저, `프라미스 성공!`이 나중에 출력되는 것을 볼 수 있습니다.
18
+
예시를 실행하면 '코드 종료'가 먼저, '프라미스 성공!'이 나중에 출력되는 것을 볼 수 있습니다.
19
19
20
20
프라미스는 즉시 이행상태가 되었는데도 말이죠. 뭔가 이상하네요.
21
21
@@ -28,7 +28,7 @@ alert("코드 종료"); // 이 얼럿 창이 가장 먼저 나타납니다.
28
28
[명세서](https://tc39.github.io/ecma262/#sec-jobs-and-job-queues)의 설명을 살펴봅시다.
29
29
30
30
- 마이크로태스크 큐는 먼저 들어온 작업을 먼저 실행합니다(FIFO, first-in-first-out).
31
-
- 실행할 것이 아무것도 남아있지 않을 때만 큐에 있는 작업이 실행되기 시작합니다.
31
+
- 실행할 것이 아무것도 남아있지 않을 때만 마이크로태스크 큐에 있는 작업이 실행되기 시작합니다.
32
32
33
33
요약하자면, 어떤 프라미스가 준비되었을 때 이 프라미스의 `.then/catch/finally` 핸들러가 큐에 들어간다고 생각하시면 됩니다. 이때 핸들러들은 여전히 실행되지 않습니다. 현재 코드에서 자유로운 상태가 되었을 때에서야 자바스크립트 엔진은 큐에서 작업을 꺼내 실행합니다.
34
34
@@ -38,9 +38,9 @@ alert("코드 종료"); // 이 얼럿 창이 가장 먼저 나타납니다.
38
38
39
39
프라미스 핸들러는 항상 내부 큐를 통과하게 됩니다.
40
40
41
-
`.then/catch/finally`가 여러 개 있어서 체인이 만들어진 경우엔 모든 핸들러가 각각 비동기로 실행됩니다. 각 핸들러는 먼저 큐에 들어갔다가 현재 코드가 완료되고, 큐에 있는 이전 핸들러의 실행이 완료되었을 때 실행됩니다.
41
+
여러 개의 `.then/catch/finally`를 사용해 만든 체인의 경우, 각 핸들러는 비동기적으로 실행됩니다. 큐에 들어간 핸들러 각각은 현재 코드가 완료되고, 큐에 적체된 이전 핸들러의 실행이 완료되었을 때 실행됩니다.
42
42
43
-
**그런데 실행 순서가 중요해서 `코드 종료`를 `프라미스 성공!`보다 나중에 출력되게 하려면 어떻게 해야 할까요?**
43
+
**그렇다면 '프라미스 성공!'을 먼저, '코드 종료'를 나중에 출력되게 하려면 어떻게 해야 할까요?**실행 순서가 중요한 경우엔 이런 요구사항이 충족되도록 코드를 작성해야 합니다.
44
44
45
45
방법은 아주 쉽습니다. `.then`을 사용해 큐에 넣으면 됩니다.
46
46
@@ -60,7 +60,7 @@ Promise.resolve()
60
60
61
61
**'처리되지 못한 거부'는 마이크로태스크 큐 끝에서 프라미스 에러가 처리되지 못할 때 발생합니다.**
62
62
63
-
정상적인 경우라면 에러가 생길 것을 대비하여 프라미스 체인에 `.catch`를 추가해 에러를 처리합니다.
63
+
정상적인 경우라면 개발자는 에러가 생길 것을 대비하여 프라미스 체인에 `.catch`를 추가해 에러를 처리합니다.
64
64
65
65
```js run
66
66
let promise =Promise.reject(newError("프라미스 실패!"));
예시를 실행하면 `프라미스 실패!`가 먼저, `잡았다!`가 나중에 출력되는 걸 확인할 수 있습니다.
96
+
예시를 실행하면 `프라미스 실패!`가 먼저, `잡았다!`가 나중에 출력되는 걸 확인할 수 있습니다.
97
97
98
98
마이크로태스크 큐에 대해 몰랐다면 "에러를 잡았는데도 왜 `unhandledrejection` 핸들러가 실행되는 거지?"라는 의문을 가졌을 겁니다.
99
99
100
-
이제 우리는 마이크로태스크 큐에 있는 작업 모두가 완료되었을 때 `unhandledrejection`이 실행된다는 것을 알기 때문에 이런 의문을 품지 않을 겁니다. 엔진은 프라미스를 검사하고 이 중 하나라도 '거부(rejected)' 상태이면 `unhandledrejection` 핸들러를 트리거 하기 때문입니다.
100
+
`unhandledrejection`은 마이크로태스크 큐에 있는 작업 모두가 완료되었을 때 생성됩니다. 엔진은 프라미스들을 검사하고 이 중 하나라도 '거부(rejected)' 상태이면 `unhandledrejection` 핸들러를 트리거 하죠. 이로써 앞선 의문이 자연스레 해결되었습니다.
101
101
102
-
위 예시에서 `setTimeout`에 의해 추가된`.catch`는 트리거 되긴 하는데, `unhandledrejection`이 만들어진 이후에 트리거 되므로`.catch`가 있어도`프라미스 실패!`가 출력됩니다.
102
+
위 예시를 실행하면 `setTimeout`을 사용해 추가한`.catch` 역시 트리거 됩니다. 다만 `.catch`는 `unhandledrejection`이 발생한 이후에 트리거 되므로 `프라미스 실패!`가 출력됩니다.
103
103
104
104
## 요약
105
105
106
-
모든 프라미스 동작은 내부 '마이크로태스크 큐'(ES8 용어)라고도 불리는 '프라미스 잡(promise job)' 큐에 들어가서 처리되기 때문에 프라미스 핸들링은 항상 비동기로 처리됩니다.
106
+
모든 프라미스 동작은 '마이크로태스크 큐'(ES8 용어)라 불리는 내부 '프라미스 잡(promise job)' 큐에 들어가서 처리되기 때문에 프라미스 핸들링은 항상 비동기로 처리됩니다.
107
107
108
108
따라서 `.then/catch/finally` 핸들러는 항상 현재 코드가 종료되고 난 후에 호출됩니다.
109
109
110
110
어떤 코드 조각을 `.then/catch/finally`가 호출된 이후에 실행하고 싶다면 `.then`을 체인에 추가하고 이 안에 코드 조각을 넣으면 됩니다.
111
111
112
-
브라우저와 Node.js를 포함하는 대부분의 자바스크립트 엔진에선, 마이크로태스크가 '이벤트 루프(event loop)'와 '매크로태스크(macrotask)'와 깊은 연관 관계를 맺습니다. 이 둘은 프라미스와는 직접적인 연관성이 없기 때문에, <info:event-loop>에서 따로 다루도록 하겠습니다.
112
+
브라우저와 Node.js를 포함한 대부분의 자바스크립트 엔진에선, 마이크로태스크가 '이벤트 루프(event loop)'와 '매크로태스크(macrotask)'와 깊은 연관 관계를 맺습니다. 이 둘은 프라미스와는 직접적인 연관성이 없기 때문에, <info:event-loop>에서 따로 다루도록 하겠습니다.
0 commit comments