aboutsummaryrefslogtreecommitdiff
path: root/files/ko/web/javascript/reference/global_objects/promise/all/index.html
blob: a38a3fd82e56d9e26f208290ec30ab6f6bd6f799 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
---
title: Promise.all()
slug: Web/JavaScript/Reference/Global_Objects/Promise/all
tags:
  - ECMAScript 2015
  - JavaScript
  - Method
  - Promise
translation_of: Web/JavaScript/Reference/Global_Objects/Promise/all
---
<div>{{JSRef}}</div>

<p><code><strong>Promise.all()</strong></code> 메서드는 순회 가능한 객체에 주어진 모든 프로미스가 이행한 후, 혹은 프로미스가 주어지지 않았을 때 이행하는 {{jsxref("Promise")}}를 반환합니다. 주어진 프로미스 중 하나가 거부하는 경우, 첫 번째로 거절한 프로미스의 이유를 사용해 자신도 거부합니다.</p>

<div>{{EmbedInteractiveExample("pages/js/promise-all.html")}}</div>

<h2 id="구문">구문</h2>

<pre class="syntaxbox">Promise.all(<var>iterable</var>);
</pre>

<h3 id="매개변수">매개변수</h3>

<dl>
 <dt><code>iterable</code></dt>
 <dd>{{jsxref("Array")}}와 같이 <a href="/ko/docs/Web/JavaScript/Reference/Iteration_protocols#The_iterable_protocol">순회 가능</a>한(iterable) 객체.</dd>
</dl>

<h3 id="반환_값">반환 값</h3>

<ul>
 <li>매개변수로 주어진 순회 가능한 객체가 비어 있으면 <strong>이미 이행한</strong> {{jsxref("Promise")}}.</li>
 <li>객체에 프로미스가 없으면, <strong>비동기적으로 이행하는</strong> {{jsxref("Promise")}}. 단, Google Chrome 58은 <strong>이미 이행한</strong> 프로미스를 반환합니다.</li>
 <li>그렇지 않은 경우, <strong>대기 중</strong>{{jsxref("Promise")}}. 결과로 반환하는 프로미스는 인자의 모든 프로미스가 이행하거나 어떤 프로미스가 거부할 때 (호출 스택이 비는 즉시) <strong>비동기적으로</strong> 이행/거부합니다. "<code>Promise.all</code>의 동기성/비동기성" 예제를 참고하세요. 반환하는 프로미스의 이행 값은 매개변수로 주어진 프로미스의 순서와 일치하며, 완료 순서에 영향을 받지 않습니다.</li>
</ul>

<h2 id="설명">설명</h2>

<p>이 메서드는 여러 프로미스의 결과를 집계할 때 유용하게 사용할 수 있습니다. 일반적으로 다음 코드를 계속 실행하기 전에 서로 연관된 비동기 작업 여러 개가 모두 이행되어야 하는 경우에 사용됩니다.</p>

<p>입력 값으로 들어온 프로미스 중 <strong>하나라도</strong> 거부 당하면 <code>Promise.all()</code>은 즉시 거부합니다. 이에 비해, {{jsxref("Promise.allSettled()")}}가 반환하는 프로미스는 이행/거부 여부에 관계없이 주어진 프로미스가 모두 완료될 때까지 기다립니다. 결과적으로, 주어진 이터러블의 모든 프로미스와 함수의 결과 값을 최종적으로 반환합니다.</p>

<h3 id="이행">이행</h3>

<p>반환한 프로미스의 이행 결과값은 (프로미스가 아닌 값을 포함하여) 매개변수로 주어진 순회 가능한 객체에 포함된 <strong>모든</strong> 값을 담은 배열입니다.</p>

<ul>
 <li>빈 객체를 전달한 경우, (동기적으로) 이미 이행한 프로미스를 반환합니다.</li>
 <li>전달받은 모든 프로미스가 이미 이행되어 있거나 프로미스가 없는 경우, 비동기적으로 이행하는 프로미스를 반환합니다.</li>
</ul>

<h3 id="거부">거부</h3>

<p>주어진 프로미스 중 하나라도 거부하면, 다른 프로미스의 이행 여부에 상관없이 첫 번째 거부 이유를 사용해 거부합니다.</p>

<h2 id="예제">예제</h2>

<h3 id="Promise.all_사용하기"><code>Promise.all</code> 사용하기</h3>

<p><code>Promise.all</code>은 배열 내 모든 값의 이행(또는 첫 번째 거부)을 기다립니다.</p>

<pre class="brush: js">var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) =&gt; {
  setTimeout(() =&gt; {
    resolve("foo");
  }, 100);
});

Promise.all([p1, p2, p3]).then(values =&gt; {
  console.log(values); // [3, 1337, "foo"]
});</pre>

<p>순회 가능한 객체에 프로미스가 아닌 값이 들어있다면 무시하지만, 이행 시 결과 배열에는 포함합니다.</p>

<pre class="brush: js">// 매개변수 배열이 빈 것과 동일하게 취급하므로 이행함
var p = Promise.all([1,2,3]);
// 444로 이행하는 프로미스 하나만 제공한 것과 동일하게 취급하므로 이행함
var p2 = Promise.all([1,2,3, Promise.resolve(444)]);
// 555로 거부하는 프로미스 하나만 제공한 것과 동일하게 취급하므로 거부함
var p3 = Promise.all([1,2,3, Promise.reject(555)]);

// setTimeout()을 사용해 스택이 빈 후에 출력할 수 있음
setTimeout(function() {
    console.log(p);
    console.log(p2);
    console.log(p3);
});

// 출력
// Promise { &lt;state&gt;: "fulfilled", &lt;value&gt;: Array[3] }
// Promise { &lt;state&gt;: "fulfilled", &lt;value&gt;: Array[4] }
// Promise { &lt;state&gt;: "rejected", &lt;reason&gt;: 555 }</pre>

<h3 id="Promise.all의_동기성비동기성"><code>Promise.all</code>의 동기성/비동기성</h3>

<p>다음 예제는 <code>Promise.all</code>의 비동기성(주어진 인자가 빈 경우엔 동기성)을 보입니다.</p>

<pre class="brush: js">// Promise.all을 최대한 빨리 완료시키기 위해
// 이미 이행된 프로미스로 배열을 만들어 인자로 전달
var resolvedPromisesArray = [Promise.resolve(33), Promise.resolve(44)];

var p = Promise.all(resolvedPromisesArray);
// 실행 즉시 p의 값을 기록
console.log(p);

// 호출 스택을 비운 다음 실행하기 위해 setTimeout을 사용
setTimeout(function() {
    console.log('the stack is now empty');
    console.log(p);
});

// 로그 출력 결과 (순서대로):
// Promise { &lt;state&gt;: "pending" }
// the stack is now empty
// Promise { &lt;state&gt;: "fulfilled", &lt;value&gt;: Array[2] }
</pre>

<p><code>Promise.all()</code>이 거부하는 경우에도 동일한 일이 발생합니다:</p>

<pre class="brush: js">var mixedPromisesArray = [Promise.resolve(33), Promise.reject(44)];
var p = Promise.all(mixedPromisesArray);
console.log(p);
setTimeout(function() {
    console.log('the stack is now empty');
    console.log(p);
});

// 출력
// Promise { &lt;state&gt;: "pending" }
// the stack is now empty
// Promise { &lt;state&gt;: "rejected", &lt;reason&gt;: 44 }
</pre>

<p>그러나, <code>Promise.all</code>은 주어진 순회 가능한 객체가 비어있는 경우에만 동기적으로 이행됩니다.</p>

<pre class="brush: js">var p = Promise.all([]); // 즉시 이행함
var p2 = Promise.all([1337, "hi"]); // 프로미스가 아닌 값은 무시하지만 비동기적으로 실행됨
console.log(p);
console.log(p2);
setTimeout(function() {
    console.log('the stack is now empty');
    console.log(p2);
});

// 출력
// Promise { &lt;state&gt;: "fulfilled", &lt;value&gt;: Array[0] }
// Promise { &lt;state&gt;: "pending" }
// the stack is now empty
// Promise { &lt;state&gt;: "fulfilled", &lt;value&gt;: Array[2] }
</pre>

<h3 id="Promise.all()_실패_우선성"><code>Promise.all()</code> 실패 우선성</h3>

<p><code>Promise.all()</code>은 배열 내 요소 중 어느 하나라도 거부하면 즉시 거부합니다. 예를 들어, 일정 시간이 지난 이후 이행하는 네 개의 프로미스와, 즉시 거부하는 하나의 프로미스를 전달한다면 <code>Promise.all()</code>도 즉시 거부합니다.</p>

<pre class="brush: js">var p1 = new Promise((resolve, reject) =&gt; {
  setTimeout(() =&gt; resolve('하나'), 1000);
});
var p2 = new Promise((resolve, reject) =&gt; {
  setTimeout(() =&gt; resolve('둘'), 2000);
});
var p3 = new Promise((resolve, reject) =&gt; {
  setTimeout(() =&gt; resolve('셋'), 3000);
});
var p4 = new Promise((resolve, reject) =&gt; {
  setTimeout(() =&gt; resolve('넷'), 4000);
});
var p5 = new Promise((resolve, reject) =&gt; {
  reject(new Error('거부'));
});


// .catch 사용:
Promise.all([p1, p2, p3, p4, p5])
.then(values =&gt; {
  console.log(values);
})
.catch(error =&gt; {
  console.log(error.message)
});

// 콘솔 출력값:
// "거부"
</pre>

<p>발생할 수 있는 거부를 사전에 처리해 동작 방식을 바꿀 수 있습니다.</p>

<pre class="brush: js">var p1 = new Promise((resolve, reject) =&gt; {
  setTimeout(() =&gt; resolve('p1_지연_이행'), 1000);
});

var p2 = new Promise((resolve, reject) =&gt; {
  reject(new Error('p2_즉시_거부'));
});

Promise.all([
  p1.catch(error =&gt; { return error }),
  p2.catch(error =&gt; { return error }),
]).then(values =&gt; {
  console.log(values[0]) // "p1_지연_이행"
  console.log(values[1]) // "Error: p2_즉시_거부"
})
</pre>

<h2 id="명세">명세</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
  <tr>
   <td>{{SpecName('ES2015', '#sec-promise.all', 'Promise.all')}}</td>
   <td>{{Spec2('ES2015')}}</td>
   <td>Initial definition in an ECMA standard.</td>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-promise.all', 'Promise.all')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td></td>
  </tr>
 </tbody>
</table>

<h2 id="브라우저_호환성">브라우저 호환성</h2>

<p>{{Compat("javascript.builtins.Promise.all")}}</p>

<h2 id="같이_보기">같이 보기</h2>

<ul>
 <li>{{jsxref("Promise")}}</li>
 <li>{{jsxref("Promise.race()")}}</li>
</ul>