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
`loadScript(src, callback)`를 이제 프라미스화해봅시다. 새로운 함수 `loadScriptPromise(src)`는 `loadScript`와 동일하게 동작하지만 `callback`을 제외한 `src`만 인수로 받아야 하고, 프라미스를 반환해야 합니다.
32
-
=======
33
-
The function loads a script with the given `src`, and then calls `callback(err)` in case of an error, or `callback(null, script)` in case of successful loading. That's a widespread agreement for using callbacks, we saw it before.
34
-
>>>>>>> upstream/master
26
+
이 함수는 주어진 `src`의 스크립트를 불러온 뒤, 에러가 발생하면 `callback(err)`를 호출하고 로딩에 성공하면 `callback(null, script)`를 호출합니다. 앞서 살펴본 것처럼 콜백을 사용할 때 널리 쓰이는 방식입니다.
35
27
36
-
Let's promisify it.
28
+
이제 이 함수를 프라미스화해봅시다.
37
29
38
-
We'll make a new function `loadScriptPromise(src)`, that does the same (loads the script), but returns a promise instead of using callbacks.
30
+
새 함수 `loadScriptPromise(src)`를 만들겠습니다. 이 함수는 스크립트를 불러온다는 점에서 기존 함수와 동일하게 동작하지만, 콜백을 사용하는 대신 프라미스를 반환합니다.
39
31
40
-
In other words, we pass it only `src` (no `callback`) and get a promise in return, that resolves with `script` when the load is successful, and rejects with the error otherwise.
32
+
다시 말해 `callback` 없이 `src`만 전달하면 프라미스를 반환받습니다. 로딩에 성공하면 이 프라미스는 `script`와 함께 이행되고, 실패하면 에러와 함께 거부됩니다.
41
33
42
-
Here it is:
34
+
구현은 다음과 같습니다.
43
35
```js
44
36
letloadScriptPromise=function(src) {
45
37
returnnewPromise((resolve, reject) => {
@@ -54,35 +46,19 @@ let loadScriptPromise = function(src) {
54
46
// loadScriptPromise('path/script.js').then(...)
55
47
```
56
48
57
-
<<<<<<< HEAD
58
-
새롭게 구현한 `loadScriptPromise`는 프라미스 기반 코드와 잘 융화됩니다.
49
+
예시에서 볼 수 있듯이 새 함수는 기존 함수 `loadScript`를 감싸는 래퍼입니다. 새 함수는 자체 콜백을 넘겨 `loadScript`를 호출하고, 이 콜백은 결과에 따라 프라미스의 `resolve`나 `reject`를 호출합니다.
59
50
60
-
예시에서 볼 수 있듯이, `loadScriptPromise`는 기존 함수 `loadScript`에 모든 일을 위임합니다. `loadScript`의 콜백은 스크립트 로딩 상태에 따라 `이행` 혹은 `거부`상태의 프라미스를 반환합니다.
51
+
이제 `loadScriptPromise`는 프라미스 기반 코드에 잘 어울립니다. 콜백보다 프라미스를 더 선호한다면, 그리고 곧 그럴 만한 이유를 더 살펴볼 예정인데, 이제 이 함수를 사용하면 됩니다.
61
52
62
-
그런데 실무에선 함수 하나가 아닌 여러 개의 함수를 프라미스화 해야 할 겁니다. 헬퍼 함수를 만드는 게 좋을 것 같네요. 프라미스화를 적용 할 함수 `f`를 받고 래퍼 함수를 반환하는 함수 `promisify(f)`를 만들어봅시다.
53
+
실무에서는 함수 하나가 아니라 여러 함수를 프라미스화해야 할 수도 있으므로 헬퍼를 사용하는 편이 좋습니다.
63
54
64
-
`promisify(f)`가 반환하는 래퍼 함수는 위 예시와 동일하게 동작할 겁니다. 프라미스를 반환하고 호출을 기존 함수 `f`에 전달하여 커스텀 콜백 내의 결과를 추적해야 하죠.
55
+
이 헬퍼를 `promisify(f)`라고 부르겠습니다. `promisify(f)`는 프라미스화할 함수 `f`를 받고 래퍼 함수를 반환합니다.
65
56
66
57
```js
67
58
functionpromisify(f) {
68
-
returnfunction (...args) { // 래퍼 함수를 반환함
59
+
returnfunction (...args) { // 래퍼 함수를 반환함 (*)
69
60
returnnewPromise((resolve, reject) => {
70
-
functioncallback(err, result) { // f에 사용할 커스텀 콜백
71
-
=======
72
-
As we can see, the newfunction is a wrapper around the original `loadScript`function. It calls it providing its own callback that translates to promise `resolve/reject`.
73
-
74
-
Now `loadScriptPromise` fits well in promise-based code. If we like promises more than callbacks (andsoonwe'll see more reasons for that), then we will use it instead.
75
-
76
-
In practice we may need to promisify more than one function, so it makes sense to use a helper.
77
-
78
-
We'llcallit`promisify(f)`:itacceptsato-promisifyfunction `f` and returns a wrapper function.
79
-
80
-
```js
81
-
functionpromisify(f) {
82
-
returnfunction (...args) { // return a wrapper-function (*)
83
-
returnnewPromise((resolve, reject) => {
84
-
functioncallback(err, result) { // our custom callback for f (**)
85
-
>>>>>>> upstream/master
61
+
functioncallback(err, result) { // f에 사용할 커스텀 콜백 (**)
86
62
if (err) {
87
63
reject(err);
88
64
} else {
@@ -102,26 +78,18 @@ let loadScriptPromise = promisify(loadScript);
102
78
loadScriptPromise(...).then(...);
103
79
```
104
80
105
-
<<<<<<< HEAD
106
-
위 예시는 프라미스화 할 함수가 인수가 두 개(`(err, result)`)인 콜백을 받을 것이라 가정하고 작성되었습니다. 십중팔구 이런 상황일 것이고, 커스텀 콜백은 이 상황에 딱 들어맞습니다. `promisify`가 잘 동작하는 것은 말할 것도 없겠죠.
107
-
=======
108
-
The code may look a bit complex, but it's essentially the same that we wrote above, while promisifying `loadScript` function.
81
+
코드가 조금 복잡해 보일 수 있지만, 본질적으로는 위에서 `loadScript` 함수를 프라미스화할 때 작성한 코드와 같습니다.
109
82
110
-
A call to `promisify(f)` returns a wrapper around `f``(*)`. That wrapper returns a promise and forwards the call to the original `f`, tracking the result in the custom callback `(**)`.
83
+
`promisify(f)`를 호출하면 `f`를 감싸는 래퍼, 즉 `(*)`로 표시한 함수가 반환됩니다. 이 래퍼는 프라미스를 반환하고 원래 함수 `f`로 호출을 전달하며, 커스텀 콜백 `(**)`에서 결과를 추적합니다.
111
84
112
-
Here, `promisify` assumes that the original function expects a callback with exactly two arguments `(err, result)`. That's what we encounter most often. Then our custom callback is in exactly the right format, and `promisify` works great for such a case.
113
-
>>>>>>> upstream/master
85
+
여기서 `promisify`는 원래 함수가 정확히 두 개의 인수 `(err, result)`를 받는 콜백을 기대한다고 가정합니다. 이런 경우가 가장 흔합니다. 그러면 커스텀 콜백이 바로 알맞은 형식이 되고, 이런 경우 `promisify`는 잘 동작합니다.
114
86
115
87
그런데 함수 `f`가 두 개를 초과하는 인수를 가진 콜백, `callback(err, res1, res2, ...)`을 받는다면 어떤 일이 발생할까요?
116
88
117
-
<<<<<<< HEAD
118
-
이런 경우를 대비하여 좀 더 진화한 헬퍼 함수, `promisify`를 만들어 봅시다. 새롭게 만든 함수를 `promisify(f, true)`형태로 호출하면, 프라미스 결과는 콜백의 성공 케이스(`results`)를 담은 배열, `[res1, res2, ...]`이 됩니다.
119
-
=======
120
-
We can improve our helper. Let's make a more advanced version of `promisify`.
89
+
헬퍼를 개선해봅시다. 좀 더 발전된 버전의 `promisify`를 만들어 보겠습니다.
121
90
122
-
- When called as `promisify(f)` it should work similar to the version above.
123
-
- When called as `promisify(f, true)`, it should return the promise that resolves with the array of callback results. That's exactly for callbacks with many arguments.
124
-
>>>>>>> upstream/master
91
+
-`promisify(f)`로 호출하면 위 버전과 비슷하게 동작해야 합니다.
92
+
-`promisify(f, true)`로 호출하면 콜백 결과를 담은 배열로 이행되는 프라미스를 반환해야 합니다. 이는 인수가 많은 콜백을 위한 동작입니다.
125
93
126
94
```js
127
95
// 콜백의 성공 결과를 담은 배열을 얻게 해주는 promisify(f, true)
@@ -149,22 +117,14 @@ f = promisify(f, true);
149
117
f(...).then(arrayOfResults=>..., err=>...);
150
118
```
151
119
152
-
<<<<<<< HEAD
153
-
`callback(result)`같이 `err`이 없는 형태나 지금까지 언급하지 않은 형태의 이색적인 콜백도 있을 수 있는데, 이런 경우엔 헬퍼 함수를 사용하지 않고 직접 프라미스화 하면 됩니다.
154
-
=======
155
-
As you can see it's essentially the same as above, but `resolve` is called with only one or all arguments depending on whether `manyArgs` is truthy.
120
+
위 코드와 본질적으로는 같습니다. 다만 `manyArgs`가 참 같은 값인지에 따라 `resolve`를 하나의 인수로 호출할지, 전체 인수로 호출할지만 달라집니다.
156
121
157
-
For more exotic callback formats, like those without `err` at all: `callback(result)`, we can promisify such functions manually without using the helper.
158
-
>>>>>>> upstream/master
122
+
`callback(result)`처럼 `err`가 아예 없는 콜백 등 더 특이한 콜백 형식의 경우, 헬퍼를 사용하지 않고 해당 함수를 직접 프라미스화하면 됩니다.
159
123
160
124
본 챕터에서 설명한 헬퍼 함수보다 더 유용한 형태의 프라미스화를 도와주는 함수를 제공하는 모듈도 많습니다. [es6-promisify](https://github.com/digitaldesignlabs/es6-promisify)가 대표적인 예입니다. Node.js에선 내장 함수 `util.promisify`를 사용해 프라미스화를 할 수 있습니다.
161
125
162
126
```smart
163
-
<<<<<<<HEAD
164
-
프라미스화는 곧 배우게 될 `async/await`와 함께 사용하면 더 좋습니다. 다만, 콜백을 완전히 대체하지는 못한다는 사실을 기억해 두시기 바랍니다.
165
-
=======
166
-
Promisification is a great approach, especially when you use `async/await` (covered later in the chapter <info:async-await>), but not a total replacement for callbacks.
167
-
>>>>>>> upstream/master
127
+
프라미스화는 특히 이후 <info:async-await> 챕터에서 다룰 `async/await`와 함께 사용할 때 매우 유용한 접근법이지만, 콜백을 완전히 대체할 수는 없습니다.
Copy file name to clipboardExpand all lines: 1-js/11-async/07-microtask-queue/article.md
+1-17Lines changed: 1 addition & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -23,22 +23,14 @@ alert("코드 종료"); // 얼럿 창이 가장 먼저 뜹니다.
23
23
24
24
## 마이크로태스크 큐
25
25
26
-
<<<<<<< HEAD
27
26
비동기 작업을 처리하려면 적절한 관리가 필요합니다. 이를 위해 ECMA에선 `PromiseJobs`라는 내부 큐(internal queue)를 명시합니다. V8 엔진에선 이를 '마이크로태스크 큐(microtask queue)'라고 부르기 때문에 이 용어가 좀 더 선호됩니다.
28
-
=======
29
-
Asynchronous tasks need proper management. For that, the ECMA standard specifies an internal queue `PromiseJobs`, more often referred to as the "microtask queue" (V8 term).
30
-
>>>>>>> upstream/master
31
27
32
28
[명세서](https://tc39.github.io/ecma262/#sec-jobs-and-job-queues)의 설명을 살펴봅시다.
33
29
34
30
- 마이크로태스크 큐는 먼저 들어온 작업을 먼저 실행합니다(FIFO, first-in-first-out).
35
31
- 실행할 것이 아무것도 남아있지 않을 때만 마이크로태스크 큐에 있는 작업이 실행되기 시작합니다.
36
32
37
-
<<<<<<< HEAD
38
33
요약하자면, 어떤 프라미스가 준비되었을 때 이 프라미스의 `.then/catch/finally` 핸들러가 큐에 들어간다고 생각하시면 됩니다. 이때 핸들러들은 여전히 실행되지 않습니다. 현재 코드에서 자유로운 상태가 되었을 때에서야 자바스크립트 엔진은 큐에서 작업을 꺼내 실행합니다.
39
-
=======
40
-
Or, to put it more simply, when a promise is ready, its `.then/catch/finally` handlers are put into the queue; they are not executed yet. When the JavaScript engine becomes free from the current code, it takes a task from the queue and executes it.
41
-
>>>>>>> upstream/master
42
34
43
35
위 예시에서 '코드 종료'가 먼저 출력되는 이유가 여기에 있습니다.
44
36
@@ -48,11 +40,7 @@ Or, to put it more simply, when a promise is ready, its `.then/catch/finally` ha
48
40
49
41
여러 개의 `.then/catch/finally`를 사용해 만든 체인의 경우, 각 핸들러는 비동기적으로 실행됩니다. 큐에 들어간 핸들러 각각은 현재 코드가 완료되고, 큐에 적체된 이전 핸들러의 실행이 완료되었을 때 실행됩니다.
50
42
51
-
<<<<<<< HEAD
52
43
**그렇다면 '프라미스 성공!'을 먼저, '코드 종료'를 나중에 출력되게 하려면 어떻게 해야 할까요?** 실행 순서가 중요한 경우엔 이런 요구사항이 충족되도록 코드를 작성해야 합니다.
53
-
=======
54
-
**What if the order matters for us? How can we make `code finished` appear after `promise done`?**
모든 프라미스 동작은 '마이크로태스크 큐'(ES8 용어)라 불리는 내부 '프라미스 잡(promise job)' 큐에 들어가서 처리되기 때문에 프라미스 핸들링은 항상 비동기로 처리됩니다.
120
-
=======
121
-
Promise handling is always asynchronous, as all promise actions pass through the internal "promise jobs" queue, also called "microtask queue" (V8 term).
122
-
>>>>>>> upstream/master
106
+
모든 프라미스 동작은 '마이크로태스크 큐'(V8 용어)라 불리는 내부 '프라미스 잡(promise job)' 큐에 들어가서 처리되기 때문에 프라미스 핸들링은 항상 비동기로 처리됩니다.
123
107
124
108
따라서 `.then/catch/finally` 핸들러는 항상 현재 코드가 종료되고 난 후에 호출됩니다.
0 commit comments