diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:17 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:17 -0500 |
commit | da78a9e329e272dedb2400b79a3bdeebff387d47 (patch) | |
tree | e6ef8aa7c43556f55ddfe031a01cf0a8fa271bfe /files/ko/web/javascript/reference/global_objects/promise | |
parent | 1109132f09d75da9a28b649c7677bb6ce07c40c0 (diff) | |
download | translated-content-da78a9e329e272dedb2400b79a3bdeebff387d47.tar.gz translated-content-da78a9e329e272dedb2400b79a3bdeebff387d47.tar.bz2 translated-content-da78a9e329e272dedb2400b79a3bdeebff387d47.zip |
initial commit
Diffstat (limited to 'files/ko/web/javascript/reference/global_objects/promise')
10 files changed, 1518 insertions, 0 deletions
diff --git a/files/ko/web/javascript/reference/global_objects/promise/all/index.html b/files/ko/web/javascript/reference/global_objects/promise/all/index.html new file mode 100644 index 0000000000..c8a458a665 --- /dev/null +++ b/files/ko/web/javascript/reference/global_objects/promise/all/index.html @@ -0,0 +1,239 @@ +--- +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> + +<p class="hidden">해당 예제의 소스 코드는 GitHub 리포지토리에 저장되어 있습니다. 인터랙티브 데모 프로젝트에 기여하고 싶다면 <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> 를 클론하고 pull request를 보내 주세요.</p> + +<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")}}. 단, 구글 크롬 58은 <strong>이미 이행한</strong> 프로미스를 반환합니다.</li> + <li>그렇지 않은 경우, <strong>대기 중</strong>인 {{jsxref("Promise")}}. 결과로 반환하는 프로미스는 인자의 모든 프로미스가 이행하거나 어떤 프로미스가 거부할 때 (호출 스택이 비는 즉시) <strong>비동기적으로</strong> 이행/거부합니다. "<code>Promise.all</code>의 동기성/비동기성" 예제를 참고하세요. 반환하는 프로미스의 이행 값은 매개변수로 주어진 프로미스의 순서와 일치하며, 완료 순서에 영향을 받지 않습니다.</li> +</ul> + +<h2 id="설명">설명</h2> + +<p><code>Promise.all</code>은 여러 프로미스의 결과를 집계할 때 유용하게 사용할 수 있습니다.</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) => { + setTimeout(() => { + resolve("foo"); + }, 100); +}); + +Promise.all([p1, p2, p3]).then(values => { + 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 { <state>: "fulfilled", <value>: Array[3] } +// Promise { <state>: "fulfilled", <value>: Array[4] } +// Promise { <state>: "rejected", <reason>: 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 { <state>: "pending" } +// the stack is now empty +// Promise { <state>: "fulfilled", <value>: 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 { <state>: "pending" } +// the stack is now empty +// Promise { <state>: "rejected", <reason>: 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 { <state>: "fulfilled", <value>: Array[0] } +// Promise { <state>: "pending" } +// the stack is now empty +// Promise { <state>: "fulfilled", <value>: 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) => { + setTimeout(() => resolve('하나'), 1000); +}); +var p2 = new Promise((resolve, reject) => { + setTimeout(() => resolve('둘'), 2000); +}); +var p3 = new Promise((resolve, reject) => { + setTimeout(() => resolve('셋'), 3000); +}); +var p4 = new Promise((resolve, reject) => { + setTimeout(() => resolve('넷'), 4000); +}); +var p5 = new Promise((resolve, reject) => { + reject(new Error('거부')); +}); + + +// .catch 사용: +Promise.all([p1, p2, p3, p4, p5]) +.then(values => { + console.log(values); +}) +.catch(error => { + console.log(error.message) +}); + +// 콘솔 출력값: +// "거부" +</pre> + +<p>발생할 수 있는 거부를 사전에 처리해 동작 방식을 바꿀 수 있습니다.</p> + +<pre class="brush: js">var p1 = new Promise((resolve, reject) => { + setTimeout(() => resolve('p1_지연_이행'), 1000); +}); + +var p2 = new Promise((resolve, reject) => { + reject(new Error('p2_즉시_거부')); +}); + +Promise.all([ + p1.catch(error => { return error }), + p2.catch(error => { return error }), +]).then(values => { + 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> + +<div class="hidden">To contribute to this compatibility data, please write a pull request against this repository: <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a>.</div> + +<p>{{Compat("javascript.builtins.Promise.all")}}</p> + +<h2 id="같이_보기">같이 보기</h2> + +<ul> + <li>{{jsxref("Promise")}}</li> + <li>{{jsxref("Promise.race()")}}</li> +</ul> diff --git a/files/ko/web/javascript/reference/global_objects/promise/allsettled/index.html b/files/ko/web/javascript/reference/global_objects/promise/allsettled/index.html new file mode 100644 index 0000000000..a063f29c7c --- /dev/null +++ b/files/ko/web/javascript/reference/global_objects/promise/allsettled/index.html @@ -0,0 +1,66 @@ +--- +title: Promise.allSettled() +slug: Web/JavaScript/Reference/Global_Objects/Promise/allSettled +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/allSettled +--- +<p>{{JSRef}}</p> + +<p><code><strong>Promise.allSettled()</strong></code> 메소드는 배열이나 별도의 나열 가능한 객체를 통해 나열된 Promise모음이 모두 이행하거나 거부했을 때에 대한 대응을 할 수 있는 Promise 객체를 반환한다.</p> + +<div>{{EmbedInteractiveExample("pages/js/promise-allsettled.html")}}</div> + +<h2 id="문법">문법</h2> + +<pre class="syntaxbox"><em>Promise</em>.allSettled(<em>iterable</em>);</pre> + +<h3 id="인자">인자</h3> + +<dl> + <dt><code>iterable</code></dt> + <dd><a href="/en-US/docs/Web/JavaScript/Guide/iterable">iterable</a> 객체로, 주로 배열({{jsxref("Array")}})을 사용하며, 이들의 요소들은 모두 <code>Promise</code> 객체.</dd> +</dl> + +<h3 id="반환_값">반환 값</h3> + +<p><strong>실행할</strong> {{jsxref("Promise")}} 객체로 <strong>비동기</strong> 방식으로 이행(Resolved) 및 거부(Rejected)된 결과의 모음을 담아 인자로 전달된다. 이 때 반환된 Promise 객체의 핸들러는 각 본래 Promise 객체가 담긴 배열을 전달할 것이다.</p> + +<p>각 출력 객체는 <code>status</code> 속성을 통해, <code>fulfilled</code>,상태로 전달되면 <code>value</code> 속성이 전달되고, <code>rejected</code> 상태로 전달 시 <code>reason</code> 속성으로 전달된다. 각 Promise가 어떻게 이행(또는 거부)됐는지 value 속성 및 reason 속성을 통해 알 수 있다.</p> + +<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><a href="https://tc39.es/proposal-promise-allSettled/#sec-promise.allsettled"><code>Promise.allSettled()</code> (TC39 Stage 4 Draft)</a></td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="지원_브라우저">지원 브라우저</h2> + +<p class="hidden">To contribute to this compatibility data, please write a pull request against this repository: <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a>.</p> + +<p>{{Compat("javascript.builtins.Promise.allSettled")}}</p> + +<h3 id="구현_진행_상태">구현 진행 상태</h3> + +<p>The following table provides a daily implementation status for this feature, because this feature has not yet reached cross-browser stability. The data is generated by running the relevant feature tests in <a href="https://github.com/tc39/test262">Test262</a>, the standard test suite of JavaScript, in the nightly build, or latest release of each browser's JavaScript engine.</p> + +<div>{{EmbedTest262ReportResultsTable("Promise.allSettled")}}</div> + +<h2 id="같이_보기">같이 보기</h2> + +<ul> + <li><a href="/en-US/docs/Archive/Add-ons/Techniques/Promises">Promises</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Using_promises">Using promises</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Promises">Graceful asynchronous programming with promises</a></li> + <li>{{jsxref("Promise")}}</li> + <li>{{jsxref("Promise.all()")}}</li> +</ul> diff --git a/files/ko/web/javascript/reference/global_objects/promise/finally/index.html b/files/ko/web/javascript/reference/global_objects/promise/finally/index.html new file mode 100644 index 0000000000..c75d73ab06 --- /dev/null +++ b/files/ko/web/javascript/reference/global_objects/promise/finally/index.html @@ -0,0 +1,100 @@ +--- +title: Promise.prototype.finally() +slug: Web/JavaScript/Reference/Global_Objects/Promise/finally +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/finally +--- +<div>{{JSRef}}</div> + +<p><code><strong>finally()</strong></code> 메소드는 {{jsxref("Promise")}} 객체를 반환합니다. Promise가 처리되면 충족되거나 거부되는지 여부에 관계없이 지정된 콜백 함수가 실행됩니다. 이것은 Promise가 성공적으로 수행 되었는지 거절되었는지에 관계없이 <code>Promise</code>가 처리 된 후에 코드가 무조건 한 번은 실행되는 것을 제공합니다.</p> + +<p>이것은 Promise의 {{jsxref("Promise.then", "then()")}}과 {{jsxref("Promise.catch", "catch()")}} 핸들러에서의 코드 중복을 피하게 합니다.</p> + +<h2 id="문법">문법</h2> + +<pre class="syntaxbox"><var>p.finally(onFinally)</var>; + +p.finally(function() { + // settled (fulfilled or rejected) +}); +</pre> + +<h3 id="Parameters">Parameters</h3> + +<dl> + <dt><code>onFinally</code></dt> + <dd><code>Promise</code>가 처리된 후 {{jsxref("Function")}} 이 호출됩니다.</dd> +</dl> + +<h3 id="Return_value">Return value</h3> + +<p><code>finally</code> 핸들러는 <code>onFinally</code> 라는 지정된 함수의 {{jsxref("Promise")}}가 반환됩니다.</p> + +<h2 id="설명">설명</h2> + +<p> </p> + +<p><code>finally()</code> 메서드는 결과에 관계없이 promise가 처리되면 무언가를 프로세싱 또는 정리를 수행하려는 경우에 유용합니다.</p> + +<p><code>finally()</code> 메서드는 <code>.then(onFinally, onFinally)</code> 를 호출하는 것과 매우 비슷하지만 몇 가지 차이점이 있습니다:</p> + +<p> </p> + +<ul> + <li>함수를 인라인으로 만들 때, 두 번 선언해야 하지 않고 한 번만 전달하거나 그것을 위한 변수를 만들 수 있습니다.</li> + <li><code>finally</code> 콜백은 어떠한 인수도 전달받지 않습니다, 왜냐하면 promise가 이행되었는지 또는 거부되었는지를 판단할 수 없기 때문입니다. promise의 왜 거부되었는지 또는 이행되었을때 반환되는 값이 필요하지 않거나 제공할 필요가 없을 때 활용합니다.</li> + <li>Promise.reject (3) .finally (() => {}) Promise.reject (3) .finally (() => {}) (약속 안 함) )는 3으로 거부됩니다.</li> + <li><code>Promise.resolve(2).then(() => {}, () => {})</code>(<code>undefined</code>로 해결될) 와 달리, <code>Promise.resolve(2).finally(() => {})</code> 는 값 <code>2</code>로 해결됩니다.</li> + <li>유사하게 <code>Promise.reject(3).then(() => {}, () => {})</code> (<code>undefined</code>로 거부될)와는 달리 <code>Promise.reject(3).finally(() => {})</code> 는 값 <code>3</code>로 거부됩니다.</li> +</ul> + +<div class="note"> +<p><strong>Note:</strong> <code>finally</code> 콜백에서 <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5); font-size: 16px;">throw</span></font> (또는 거부된 promise를 반환)하면 <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5); font-size: 16px;">throw()</span></font>를 호출 할 때 지정된 거부 이유로 새롭게 만들어진 promise를 반환합니다.</p> +</div> + +<h2 id="예제">예제</h2> + +<pre class="brush: js">let isLoading = true; + +fetch(myRequest).then(function(response) { + var contentType = response.headers.get("content-type"); + if(contentType && contentType.includes("application/json")) { + return response.json(); + } + throw new TypeError("Oops, we haven't got JSON!"); + }) + .then(function(json) { /* process your JSON further */ }) + .catch(function(error) { console.log(error); }) + .finally(function() { isLoading = false; }); + +</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><a href="https://github.com/tc39/proposal-promise-finally">TC39 proposal</a></td> + <td>Stage 4</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="브라우저_호환성">브라우저 호환성</h2> + +<p class="hidden">To contribute to this compatibility data, please write a pull request against this repository: <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a>.</p> + +<p>{{Compat("javascript.builtins.Promise.finally")}}</p> + +<h2 id="더보기">더보기</h2> + +<ul> + <li>{{jsxref("Promise")}}</li> + <li>{{jsxref("Promise.prototype.then()")}}</li> + <li>{{jsxref("Promise.prototype.catch()")}}</li> +</ul> diff --git a/files/ko/web/javascript/reference/global_objects/promise/index.html b/files/ko/web/javascript/reference/global_objects/promise/index.html new file mode 100644 index 0000000000..d3dbf076c5 --- /dev/null +++ b/files/ko/web/javascript/reference/global_objects/promise/index.html @@ -0,0 +1,226 @@ +--- +title: Promise +slug: Web/JavaScript/Reference/Global_Objects/Promise +tags: + - ECMAScript 2015 + - JavaScript + - Promise + - Reference + - 프로미스 +translation_of: Web/JavaScript/Reference/Global_Objects/Promise +--- +<div>{{JSRef}}</div> + +<p><strong><code>Promise</code></strong> 객체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타냅니다.</p> + +<p>Promise의 작동 방식과 Promise 사용 방법에 대해 알아보려면 먼저 <a href="https://wiki.developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Using_promises">Promise 사용 방법</a>을 읽어 보십시오.</p> + +<h2 id="설명">설명</h2> + +<p><code>Promise</code>는 프로미스가 생성될 때 꼭 알 수 있지는 않은 값을 위한 대리자로, 비동기 연산이 종료된 이후의 결과값이나 실패 이유를 처리하기 위한 처리기를 연결할 수 있도록 합니다. 프로미스를 사용하면 비동기 메서드에서 마치 동기 메서드처럼 값을 반환할 수 있습니다. 다만 최종 결과를 반환하지는 않고, 대신 프로미스를 반환해서 미래의 어떤 시점에 결과를 제공합니다.</p> + +<p><code>Promise</code>는 다음 중 하나의 상태를 가집니다.</p> + +<ul> + <li>대기(<em>pending)</em>: 이행하거나 거부되지 않은 초기 상태.</li> + <li>이행(<em>fulfilled)</em>: 연산이 성공적으로 완료됨.</li> + <li>거부(<em>rejected)</em>: 연산이 실패함.</li> +</ul> + +<p>대기 중인 프로미스는 값과 함께 <em>이행할</em> 수도, 어떤 이유(오류)로 인해 <em>거부</em>될 수 있습니다. 이행이나 거부될 때, 프로미스에 연결한 처리기는 그 프로미스의 <code>then</code> 메서드에 의해 대기열에 오릅니다. 이미 이행했거나 거부된 프로미스에 연결한 처리기도 호출하므로, 비동기 연산과 처리기 연결 사이에 경합 조건<sup>race condition</sup>은 없습니다.</p> + +<p>{{jsxref("Promise.prototype.then()")}} 및 {{jsxref("Promise.prototype.catch()")}} 메서드의 반환 값은 다른 프로미스이므로, 서로 연결할 수 있습니다.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/8633/promises.png"></p> + +<div class="note"> +<p><strong>혼동 주의:</strong> 느긋한 계산법 및 연산 연기를 위한 방법을 프로미스라고 부르는 다른 언어(예: Scheme)가 여럿 있습니다. 반면 JavaScript에서 프로미스는 콜백 함수를 연결할 수 있는 이미 진행 중인 프로세스를 나타냅니다. 표현식을 느긋하게 평가하려면 인수 없는 <a href="/ko/docs/Web/JavaScript/Reference/Functions/애로우_펑션">화살표 함수</a> <code>f = () => <em>expression</em></code>를 사용하고, <code>f()</code>를 사용해 평가하세요.</p> +</div> + +<div class="note"> +<p><strong>참고</strong>: 프로미스는 대기 중이지 않으며 이행 또는 거부됐을 때 처리(settled)됐다고 말합니다. 프로미스와 함께 쓰이는 단어 resolved는 프로미스가 다른 프로미스의 상태에 맞춰 처리됨, 또는 상태가 "잠김"되었다는 의미입니다. 용어에 관한 더 자세한 설명은 Domenic Denicola의 글 <a href="https://github.com/domenic/promises-unwrapping/blob/master/docs/states-and-fates.md" title="States and fates">States and fates</a>에서 볼 수 있습니다.</p> +</div> + +<h2 id="생성자">생성자</h2> + +<dl> + <dt>{{jsxref("Promise.Promise", "Promise()")}}</dt> + <dd>이미 프로미스를 지원하지 않는 함수를 감쌀 때 주로 사용합니다.</dd> +</dl> + +<h2 id="속성">속성</h2> + +<dl> + <dt><code>Promise.length</code></dt> + <dd>값이 언제나 1인 길이 속성입니다. (생성자 인수의 수)</dd> + <dt>{{jsxref("Promise.prototype")}}</dt> + <dd><code>Promise</code> 생성자의 프로토타입을 나타냅니다.</dd> +</dl> + +<h2 id="메서드">메서드</h2> + +<dl> + <dt>{{jsxref("Promise.all", "Promise.all(iterable)")}}</dt> + <dd><code>iterable</code> 내의 모든 프로미스가 이행한 뒤 이행하고, 어떤 프로미스가 거부하면 즉시 거부하는 프로미스를 반환합니다. 반환된 프로미스가 이행하는 경우 <code>iterable</code> 내의 프로미스가 결정한 값을 모은 배열이 이행 값입니다. 반환된 프로미스가 거부하는 경우 <code>iterable</code> 내의 거부한 프로미스의 이유를 그대로 사용합니다. 이 메서드는 여러 프로미스의 결과를 모을 때 유용합니다.</dd> + <dt>{{jsxref("Promise.race", "Promise.race(iterable)")}}</dt> + <dd><code>iterable</code> 내의 어떤 프로미스가 이행하거나 거부하는 즉시 스스로 이행하거나 거부하는 프로미스를 반환합니다. 이행 값이나 거부 이유는 원 프로미스의 값이나 이유를 그대로 사용합니다.</dd> +</dl> + +<dl> + <dt>{{jsxref("Promise.reject()")}}</dt> + <dd>주어진 이유로 거부하는 <code>Promise</code> 객체를 반환합니다.</dd> +</dl> + +<dl> + <dt>{{jsxref("Promise.resolve()")}}</dt> + <dd>주어진 값으로 이행하는 <code>Promise</code> 객체를 반환합니다. 값이 <code>then</code> 가능한 (즉, <code>then</code> 메서드가 있는) 경우, 반환된 프로미스는 <code>then</code> 메서드를 따라가고 마지막 상태를 취합니다. 그렇지 않은 경우 반환된 프로미스는 주어진 값으로 이행합니다. 어떤 값이 프로미스인지 아닌지 알 수 없는 경우, {{jsxref("Promise.resolve", "Promise.resolve(value)")}} 후 반환값을 프로미스로 처리할 수 있습니다.</dd> +</dl> + +<h2 id="Promise_프로토타입"><code>Promise</code> 프로토타입</h2> + +<h3 id="속성_2">속성</h3> + +<p>{{page('ko/docs/Web/JavaScript/Reference/Global_Objects/Promise/prototype','속성')}}</p> + +<h3 id="메서드_2">메서드</h3> + +<p>{{page('ko/docs/Web/JavaScript/Reference/Global_Objects/Promise/prototype','메서드')}}</p> + +<h2 id="예제">예제</h2> + +<h3 id="기본_예제">기본 예제</h3> + +<pre class="brush: js notranslate">let myFirstPromise = new Promise((resolve, reject) => { + // We call resolve(...) when what we were doing asynchronously was successful, and reject(...) when it failed. + // In this example, we use setTimeout(...) to simulate async code. + // In reality, you will probably be using something like XHR or an HTML5 API. + setTimeout(function(){ + resolve("Success!"); // Yay! Everything went well! + }, 250); +}); + +myFirstPromise.then((successMessage) => { + // successMessage is whatever we passed in the resolve(...) function above. + // It doesn't have to be a string, but if it is only a succeed message, it probably will be. + console.log("Yay! " + successMessage); +});</pre> + +<h3 id="고급_예제">고급 예제</h3> + +<div class="hidden"> +<pre class="brush: html notranslate"><button id="btn">프로미스 만들기!</button> +<div id="log"></div></pre> +</div> + +<p>다음의 작은 예제는 <code>Promise</code>의 동작 방식을 보여줍니다. <code>testPromise()</code> 함수는 {{HTMLElement("button")}}을 클릭할 때마다 호출되며, {{domxref("window.setTimeout()")}}을 사용해 1~3초의 무작위 간격 이후 프로미스 횟수(1부터 시작하는 숫자)로 이행하는 프로미스를 생성합니다. <code>Promise()</code> 생성자는 프로미스를 만드는 데 쓰입니다.</p> + +<p>프로미스 이행은 {{jsxref("Promise.prototype.then()","p1.then()")}}을 사용하는 이행 콜백 세트를 통해 단순히 로그에 남습니다. 약간의 로그를 통해, 함수의 동기 부분이 비동기적 프로미스의 완료와 어떻게 분리되어 있는지 확인할 수 있습니다.</p> + +<pre class="brush: js notranslate">'use strict'; +var promiseCount = 0; + +function testPromise() { + var thisPromiseCount = ++promiseCount; + + var log = document.getElementById('log'); + log.insertAdjacentHTML('beforeend', thisPromiseCount + + ') 시작 (<small>동기적 코드 시작</small>)<br/>'); + + // 새 프로미스 생성 - 프로미스의 생성 순서를 전달하겠다는 약속을 함 (3초 기다린 후) + var p1 = new Promise( + // 실행 함수는 프로미스를 이행(resolve)하거나 + // 거부(reject)할 수 있음 + function(resolve, reject) { + log.insertAdjacentHTML('beforeend', thisPromiseCount + + ') 프로미스 시작 (<small>비동기적 코드 시작</small>)<br/>'); + // setTimeout은 비동기적 코드를 만드는 예제에 불과 + window.setTimeout( + function() { + // 프로미스 이행 ! + resolve(thisPromiseCount); + }, Math.random() * 2000 + 1000); + } + ); + + // 프로미스를 이행했을 때 할 일은 then() 호출로 정의하고, + // 거부됐을 때 할 일은 catch() 호출로 정의 + p1.then( + // 이행 값 기록 + function(val) { + log.insertAdjacentHTML('beforeend', val + + ') 프로미스 이행 (<small>비동기적 코드 종료</small>)<br/>'); + }) + .catch( + // 거부 이유 기록 + function(reason) { + console.log('여기서 거부된 프로미스(' + reason + ')를 처리하세요.'); + }); + + log.insertAdjacentHTML('beforeend', thisPromiseCount + + ') 프로미스 생성 (<small>동기적 코드 종료</small>)<br/>'); +} +</pre> + +<div class="hidden"> +<pre class="brush: js notranslate">if ("Promise" in window) { + var btn = document.getElementById("btn"); + btn.addEventListener("click", testPromise); +} else { + log = document.getElementById('log'); + log.innerHTML = "Live example not available as your browser doesn't support the <code>Promise<code> interface."; +}</pre> +</div> + +<p>이 예제는 버튼을 클릭하면 실행됩니다. <code>Promise</code>를 지원하는 브라우저가 필요합니다. 짧은 시간 안에 버튼을 여러 번 클릭하여, 서로 다른 프로미스가 번갈아 이행되는 것을 볼 수도 있습니다.</p> + +<p>{{EmbedLiveSample("고급_예제", "500", "200")}}</p> + +<h2 id="XHR로_이미지_불러오기">XHR로 이미지 불러오기</h2> + +<p>이미지를 로드하기 위해 <code>Promise</code> 및 {{domxref("XMLHttpRequest")}}를 사용하는 또 다른 간단한 예는 MDN GitHub <a href="https://github.com/mdn/js-examples/tree/master/promises-test">js-examples</a> 저장소에서 이용할 수 있습니다. <a href="http://mdn.github.io/promises-test/">실제 예</a>를 볼 수도 있습니다. 각 단계에 주석이 붙어있어, 프로미스 및 XHR 구조를 차근차근 따라갈 수 있습니다.</p> + +<h2 id="명세">명세</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">명세</th> + <th scope="col">상태</th> + <th scope="col">설명</th> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-promise-objects', 'Promise')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>ECMA 표준에서 초기 정의.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-promise-objects', 'Promise')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="브라우저_호환성">브라우저 호환성</h2> + +<div> + + +<p>{{Compat("javascript.builtins.Promise")}}</p> +</div> + +<h2 id="같이_보기">같이 보기</h2> + +<ul> + <li><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Using_promises">프로미스 사용하기</a></li> + <li><a href="http://promisesaplus.com/">Promises/A+ 스펙</a></li> + <li><a href="https://medium.com/@ramsunvtech/promises-of-promise-part-1-53f769245a53">Venkatraman.R - JS Promise (Part 1, Basics)</a></li> + <li><a href="https://medium.com/@ramsunvtech/js-promise-part-2-q-js-when-js-and-rsvp-js-af596232525c#.dzlqh6ski">Venkatraman.R - JS Promise (Part 2 - Using Q.js, When.js and RSVP.js)</a></li> + <li><a href="https://tech.io/playgrounds/11107/tools-for-promises-unittesting/introduction">Venkatraman.R - Tools for Promises Unit Testing</a></li> + <li><a href="http://www.html5rocks.com/en/tutorials/es6/promises/">Jake Archibald: JavaScript Promises: There and Back Again</a></li> + <li><a href="http://de.slideshare.net/domenicdenicola/callbacks-promises-and-coroutines-oh-my-the-evolution-of-asynchronicity-in-javascript">Domenic Denicola: Callbacks, Promises, and Coroutines – Asynchronous Programming Patterns in JavaScript</a></li> + <li><a href="http://www.mattgreer.org/articles/promises-in-wicked-detail/">Matt Greer: JavaScript Promises ... In Wicked Detail</a></li> + <li><a href="https://www.promisejs.org/">Forbes Lindesay: promisejs.org</a></li> + <li><a href="https://github.com/jakearchibald/es6-promise/">Promise polyfill</a></li> + <li><a href="https://www.udacity.com/course/javascript-promises--ud898">Udacity: JavaScript Promises</a></li> +</ul> diff --git a/files/ko/web/javascript/reference/global_objects/promise/promise/index.html b/files/ko/web/javascript/reference/global_objects/promise/promise/index.html new file mode 100644 index 0000000000..531b82dbca --- /dev/null +++ b/files/ko/web/javascript/reference/global_objects/promise/promise/index.html @@ -0,0 +1,78 @@ +--- +title: Promise() 생성자 +slug: Web/JavaScript/Reference/Global_Objects/Promise/Promise +tags: + - Constructor + - JavaScript + - Promise + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/Promise +--- +<div>{{JSRef}}</div> + +<p><strong><code>Promise</code></strong> 생성자는 주로 프로미스를 지원하지 않는 함수를 감쌀 때 사용합니다.</p> + +<div>{{EmbedInteractiveExample("pages/js/promise-constructor.html")}}</div> + +<p class="hidden">The source for this interactive demo is stored in a GitHub repository. If you'd like to contribute to the interactive demo project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</p> + +<h2 id="구문">구문</h2> + +<pre class="syntaxbox">new Promise(<var>executor</var>)</pre> + +<h3 id="매개변수">매개변수</h3> + +<dl> + <dt><code>executor</code></dt> + <dd><code>resolve</code> 및 <code>reject</code> 인수를 전달할 실행 함수. 실행 함수는 프로미스 구현에 의해 <code>resolve</code>와 <code>reject</code> 함수를 받아 즉시 실행됩니다(실행 함수는 <code>Promise</code> 생성자가 생성한 객체를 반환하기도 전에 호출됩니다). <code>resolve</code> 및 <code>reject</code> 함수는 호출할 때 각각 프로미스를 이행하거나 거부합니다. 실행 함수는 보통 어떤 비동기 작업을 시작한 후 모든 작업을 끝내면 <code>resolve</code>를 호출해 프로미스를 이행하고, 오류가 발생한 경우 <code>reject</code>를 호출해 거부합니다. 실행 함수에서 오류를 던지면 프로미스는 거부됩니다. 실행 함수의 반환값은 무시됩니다.</dd> +</dl> + +<h2 id="예제">예제</h2> + +<p><code>Promise</code> 객체는 <code>new</code> 키워드와 생성자를 사용해 만듭니다. 생성자는 매개변수로 "실행 함수"를 받습니다. 이 함수는 매개 변수로 두 가지 함수를 받아야 하는데, 첫 번째 함수(<code>resolve</code>)는 비동기 작업을 성공적으로 완료해 결과를 값으로 반환할 때 호출해야 하고, 두 번째 함수(<code>reject</code>)는 작업이 실패하여 오류의 원인을 반환할 때 호출하면 됩니다. 두 번째 함수는 주로 오류 객체를 받습니다.</p> + +<pre class="brush: js;">const myFirstPromise = new Promise((resolve, reject) => { + // do something asynchronous which eventually calls either: + // + // resolve(someValue) // fulfilled + // or + // reject("failure reason") // rejected +}); +</pre> + +<p>함수에 프로미스 기능을 추가하려면, 간단하게 프로미스를 반환하도록 하면 됩니다.</p> + +<pre class="brush: js;">function myAsyncFunction(url) { + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest() + xhr.open("GET", url) + xhr.onload = () => resolve(xhr.responseText) + xhr.onerror = () => reject(xhr.statusText) + xhr.send() + }); +}</pre> + +<h2 id="명세">명세</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-promise-constructor', 'Promise constructor')}}</td> + </tr> + </tbody> +</table> + +<h2 id="브라우저_호환성">브라우저 호환성</h2> + +<div class="hidden">To contribute to this compatibility data, please write a pull request against this repository: <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a>.</div> + +<p>{{Compat("javascript.builtins.Promise.Promise")}}</p> + +<h2 id="같이_보기">같이 보기</h2> + +<ul> + <li><a href="/ko/docs/Web/JavaScript/Guide/Using_promises">프로미스 사용하기</a></li> +</ul> diff --git a/files/ko/web/javascript/reference/global_objects/promise/prototype/index.html b/files/ko/web/javascript/reference/global_objects/promise/prototype/index.html new file mode 100644 index 0000000000..4569b4d26a --- /dev/null +++ b/files/ko/web/javascript/reference/global_objects/promise/prototype/index.html @@ -0,0 +1,71 @@ +--- +title: Promise.prototype +slug: Web/JavaScript/Reference/Global_Objects/Promise/prototype +tags: + - JavaScript + - Promise + - Property + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Promise +--- +<div>{{JSRef}}</div> + +<p><strong><code>Promise.prototype</code></strong> 속성은 {{jsxref("Promise")}} 생성자의 프로토타입을 나타냅니다.</p> + +<div>{{js_property_attributes(0,0,0)}}</div> + +<h2 id="설명">설명</h2> + +<p>{{jsxref("Promise")}} 인스턴스는 {{jsxref("Promise.prototype")}}을 상속합니다. 모든 <code>Promise</code> 인스턴스에 속성 또는 메서드를 추가하기 위해 생성자의 프로토타입 객체를 사용할 수 있습니다.</p> + +<h2 id="속성">속성</h2> + +<dl> + <dt><code>Promise.prototype.constructor</code></dt> + <dd>인스턴스의 프로토타입을 만드는 함수를 반환합니다. 기본값은 {{jsxref("Promise")}} 함수입니다.</dd> +</dl> + +<h2 id="메서드">메서드</h2> + +<dl> + <dt>{{jsxref("Promise.prototype.catch()")}}</dt> + <dd>프로미스(promise)에 거부 처리기 콜백을 추가하고 호출된 경우 콜백의 반환값 또는 프로미스가 대신 이행된 경우 그 원래 이행(fulfillment)값으로 결정하는(resolving) 새 프로미스를 반환합니다.</dd> + <dt>{{jsxref("Promise.prototype.then()")}}</dt> + <dd>프로미스에 이행 또는 거부 처리기를 추가하고 호출된 처리기의 반환값 또는 프로미스가 처리되지 않은 경우 그 원래 처리된(settled) 값으로 결정하는 새 프로미스를 반환합니다 (즉 관련 처리기 <code>onFulfilled</code> 또는 <code>onRejected</code>가 <code>undefined</code>인 경우).</dd> + <dt>{{jsxref("Promise.prototype.finally()")}}</dt> + <dd>Appends a handler to the promise, and returns a new promise which is resolved when the original promise is resolved. The handler is called when the promise is settled, whether fulfilled or rejected.</dd> +</dl> + +<h2 id="명세">명세</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">명세</th> + <th scope="col">상태</th> + <th scope="col">설명</th> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-promise.prototype', 'Promise.prototype')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>초기 정의.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-promise.prototype', 'Promise.prototype')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="브라우저_호환성">브라우저 호환성</h2> + +<p class="hidden">The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p> + +<p>{{Compat("javascript.builtins.Promise.prototype")}}</p> + +<h2 id="같이_보기">같이 보기</h2> + +<ul> + <li>{{jsxref("Promise")}}</li> +</ul> diff --git a/files/ko/web/javascript/reference/global_objects/promise/race/index.html b/files/ko/web/javascript/reference/global_objects/promise/race/index.html new file mode 100644 index 0000000000..0874d619dd --- /dev/null +++ b/files/ko/web/javascript/reference/global_objects/promise/race/index.html @@ -0,0 +1,187 @@ +--- +title: Promise.race() +slug: Web/JavaScript/Reference/Global_Objects/Promise/race +tags: + - ECMAScript 2015 + - JavaScript + - Method + - Promise + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/race +--- +<div>{{JSRef}}</div> + +<p><code><strong>Promise.race()</strong></code> 메소드는 Promise 객체를 반환합니다. 이 프로미스 객체는 iterable 안에 있는 프로미스 중에 가장 먼저 완료된 것의 결과값으로 그대로 이행하거나 거부합니다.</p> + +<div>{{EmbedInteractiveExample("pages/js/promise-race.html")}}</div> + +<p class="hidden">해당 예제의 소스 코드는 GitHub 리포지토리에 저장되어 있습니다. 인터랙티브 데모 프로젝트에 기여하고 싶다면 <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> 를 클론하고 pull request를 보내 주세요.</p> + +<h2 id="구문">구문</h2> + +<pre class="syntaxbox">Promise.race(<em>iterable</em>);</pre> + +<h3 id="매개변수">매개변수</h3> + +<dl> + <dt><code>iterable</code></dt> + <dd>{{jsxref("Array")}}와 같은 iterable 객체. <a href="/ko/docs/Web/JavaScript/Reference/Iteration_protocols">iterable</a>을 참고하세요.</dd> +</dl> + +<h3 id="반환값">반환값</h3> + +<p>주어진 iterable에서 처음으로 이행하거나 거부한 프로미스의 값을 <strong>비동기적으로</strong> 전달받는 <strong>대기 중</strong>인 {{jsxref("Promise")}}.</p> + +<h2 id="설명">설명</h2> + +<p><code>race</code> 함수는 인자로 주어진 iterable의 프로미스 중 가장 먼저 완료(settle)되는 것과 같은 방식으로 완료(이행/거부)되고, 같은 결과값을 전달하는 <code>Promise</code>를 반환합니다.</p> + +<p>전달받은 iterable이 비어 있을 경우, 반환한 프로미스는 영원히 대기 상태가 됩니다.</p> + +<p>Iterable에 프로미스가 아닌 값이나 이미 완료된 프로미스가 포함되어 있을 경우, <code>Promise.race</code>는 전달받은 iterable에서 처음으로 등장하는 이러한 값을 결과값으로 이행합니다.</p> + +<h2 id="예제">예제</h2> + +<h3 id="Promise.race의_비동기성"><font face="consolas, Liberation Mono, courier, monospace"><code>Promise.race</code>의 비동기성</font></h3> + +<p>다음 예제에서 <code>Promise.race</code>의 비동기성을 확인할 수 있습니다.</p> + +<pre class="brush: js">// Promise.race를 최대한 빨리 완료시키기 위해 +// 이미 이행된 프로미스로 배열을 만들어 인자로 전달 +var resolvedPromisesArray = [Promise.resolve(33), Promise.resolve(44)]; + +var p = Promise.race(resolvedPromisesArray); +// 실행 즉시 p의 값을 기록 +console.log(p); + +// 호출 스택을 비운 다음 실행하기 위해 setTimeout을 사용 +setTimeout(function(){ + console.log('the stack is now empty'); + console.log(p); +}); + +// 로그 출력 결과 (순서대로): +// Promise { <state>: "pending" } +// the stack is now empty +// Promise { <state>: "fulfilled", <value>: 33 }</pre> + +<p>비어 있는 iterable을 전달하면 반환한 프로미스는 영원히 대기 상태가 됩니다.</p> + +<pre class="brush: js">var foreverPendingPromise = Promise.race([]); +console.log(foreverPendingPromise); +setTimeout(function(){ + console.log('the stack is now empty'); + console.log(foreverPendingPromise); +}); + +// 로그 출력 결과 (순서대로): +// Promise { <state>: "pending" } +// the stack is now empty +// Promise { <state>: "pending" } +</pre> + +<p>Iterable에 프로미스가 아닌 값이나 이미 완료된 프로미스가 포함되어 있을 경우, <code>Promise.race</code>는 전달받은 iterable에서 처음으로 등장하는 이러한 값을 결과값으로 이행합니다.</p> + +<pre class="brush: js">var foreverPendingPromise = Promise.race([]); +var alreadyFulfilledProm = Promise.resolve(666); + +var arr = [foreverPendingPromise, alreadyFulfilledProm, "프로미스 아님"]; +var arr2 = [foreverPendingPromise, "프로미스 아님", Promise.resolve(666)]; +var p = Promise.race(arr); +var p2 = Promise.race(arr2); + +console.log(p); +console.log(p2); +setTimeout(function(){ + console.log('the stack is now empty'); + console.log(p); + console.log(p2); +}); + +// 로그 출력 결과 (순서대로): +// Promise { <state>: "pending" } +// Promise { <state>: "pending" } +// the stack is now empty +// Promise { <state>: "fulfilled", <value>: 666 } +// Promise { <state>: "fulfilled", <value>: "프로미스 아님" } +</pre> + +<h3 id="setTimeout과_함께_Promise.race_사용_예"><code>setTimeout</code>과 함께 <code>Promise.race</code> 사용 예</h3> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">var</span> p1 <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">Promise</span><span class="punctuation token">(</span><span class="keyword token">function</span><span class="punctuation token">(</span><span class="parameter token">resolve<span class="punctuation token">,</span> reject</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">setTimeout</span><span class="punctuation token">(</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="operator token">=></span> <span class="function token">resolve</span><span class="punctuation token">(</span><span class="string token">'하나'</span><span class="punctuation token">)</span><span class="punctuation token">,</span> <span class="number token">500</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">var</span> p2 <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">Promise</span><span class="punctuation token">(</span><span class="keyword token">function</span><span class="punctuation token">(</span><span class="parameter token">resolve<span class="punctuation token">,</span> reject</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">setTimeout</span><span class="punctuation token">(</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="operator token">=></span> <span class="function token">resolve</span><span class="punctuation token">(</span><span class="string token">'둘'</span><span class="punctuation token">)</span><span class="punctuation token">,</span> <span class="number token">100</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + +Promise<span class="punctuation token">.</span><span class="function token">race</span><span class="punctuation token">(</span><span class="punctuation token">[</span>p1<span class="punctuation token">,</span> p2<span class="punctuation token">]</span><span class="punctuation token">)</span> +<span class="punctuation token">.</span><span class="function token">then</span><span class="punctuation token">(</span><span class="keyword token">function</span><span class="punctuation token">(</span><span class="parameter token">value</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>value<span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// "둘"</span> + <span class="comment token">// 둘 다 이행하지만 p2가 더 빠르므로</span> +<span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + +<span class="keyword token">var</span> p3 <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">Promise</span><span class="punctuation token">(</span><span class="keyword token">function</span><span class="punctuation token">(</span><span class="parameter token">resolve<span class="punctuation token">,</span> reject</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">setTimeout</span><span class="punctuation token">(</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="operator token">=></span> <span class="function token">resolve</span><span class="punctuation token">(</span><span class="string token">'셋'</span><span class="punctuation token">)</span><span class="punctuation token">,</span> <span class="number token">100</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">var</span> p4 <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">Promise</span><span class="punctuation token">(</span><span class="keyword token">function</span><span class="punctuation token">(</span><span class="parameter token">resolve<span class="punctuation token">,</span> reject</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">setTimeout</span><span class="punctuation token">(</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="operator token">=></span> <span class="function token">reject</span><span class="punctuation token">(</span><span class="keyword token">new</span> <span class="class-name token">Error</span><span class="punctuation token">(</span><span class="string token">'넷'</span><span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">,</span> <span class="number token">500</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + +Promise<span class="punctuation token">.</span><span class="function token">race</span><span class="punctuation token">(</span><span class="punctuation token">[</span>p3<span class="punctuation token">,</span> p4<span class="punctuation token">]</span><span class="punctuation token">)</span> +<span class="punctuation token">.</span><span class="function token">then</span><span class="punctuation token">(</span><span class="keyword token">function</span><span class="punctuation token">(</span><span class="parameter token">value</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>value<span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// "셋"</span> + <span class="comment token">// p3이 더 빠르므로 이행함</span> +<span class="punctuation token">}</span><span class="punctuation token">,</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="parameter token">reason</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token">// 실행되지 않음</span> +<span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + +<span class="keyword token">var</span> p5 <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">Promise</span><span class="punctuation token">(</span><span class="keyword token">function</span><span class="punctuation token">(</span><span class="parameter token">resolve<span class="punctuation token">,</span> reject</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">setTimeout</span><span class="punctuation token">(</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="operator token">=></span> <span class="function token">resolve</span><span class="punctuation token">(</span><span class="string token">'다섯'</span><span class="punctuation token">)</span><span class="punctuation token">,</span> <span class="number token">500</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">var</span> p6 <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">Promise</span><span class="punctuation token">(</span><span class="keyword token">function</span><span class="punctuation token">(</span><span class="parameter token">resolve<span class="punctuation token">,</span> reject</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">setTimeout</span><span class="punctuation token">(</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="operator token">=></span> <span class="function token">reject</span><span class="punctuation token">(</span><span class="keyword token">new</span> <span class="class-name token">Error</span><span class="punctuation token">(</span><span class="string token">'여섯'</span><span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">,</span> <span class="number token">100</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + +Promise<span class="punctuation token">.</span><span class="function token">race</span><span class="punctuation token">(</span><span class="punctuation token">[</span>p5<span class="punctuation token">,</span> p6<span class="punctuation token">]</span><span class="punctuation token">)</span> +<span class="punctuation token">.</span><span class="function token">then</span><span class="punctuation token">(</span><span class="keyword token">function</span><span class="punctuation token">(</span><span class="parameter token">value</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token">// 실행되지 않음</span> +<span class="punctuation token">}</span><span class="punctuation token">,</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="parameter token">error</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>error<span class="punctuation token">.</span>message<span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// "여섯"</span> + <span class="comment token">// p6이 더 빠르므로 거부함</span> +<span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<h2 id="명세">명세</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">명세</th> + <th scope="col">상태</th> + <th scope="col">설명</th> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-promise.race', 'Promise.race')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>ECMA 표준에서 초기 정의.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-promise.race', 'Promise.race')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="브라우저_호환성">브라우저 호환성</h2> + +<p class="hidden">The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p> + +<p>{{Compat("javascript.builtins.Promise.race")}}</p> + +<h2 id="같이_보기">같이 보기</h2> + +<ul> + <li>{{jsxref("Promise")}}</li> + <li>{{jsxref("Promise.all()")}}</li> +</ul> diff --git a/files/ko/web/javascript/reference/global_objects/promise/reject/index.html b/files/ko/web/javascript/reference/global_objects/promise/reject/index.html new file mode 100644 index 0000000000..a376940d7e --- /dev/null +++ b/files/ko/web/javascript/reference/global_objects/promise/reject/index.html @@ -0,0 +1,81 @@ +--- +title: Promise.reject() +slug: Web/JavaScript/Reference/Global_Objects/Promise/reject +tags: + - ECMAScript6 + - JavaScript + - Method + - Promise +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/reject +--- +<div>{{JSRef}}</div> + +<p><code><strong>Promise.reject(reason)</strong></code> 메서드는 주어진 이유(reason)로 거부된 <code>Promise</code> 객체를 반환합니다.</p> + +<h2 id="구문">구문</h2> + +<pre class="syntaxbox"><var>Promise.reject(reason)</var>;</pre> + +<h3 id="매개변수">매개변수</h3> + +<dl> + <dt>reason</dt> + <dd>이 <code>Promise</code>를 거부한 이유.</dd> +</dl> + +<h2 id="설명">설명</h2> + +<p>정적 <code>Promise.reject</code> 함수는 거부된 <code>Promise</code>를 반환합니다. 디버깅 목적 및 선택된 오류를 잡기 위해, <code>reason</code>을 <code>instanceof</code> {{jsxref("Error")}} 이게 하는데 유용합니다.</p> + +<h2 id="예">예</h2> + +<h3 id="정적_Promise.reject()_메서드_사용">정적 Promise.reject() 메서드 사용</h3> + +<pre class="brush: js">Promise.reject("Testing static reject").then(function(reason) { + // 호출되지 않음 +}, function(reason) { + console.log(reason); // "Testing static reject" +}); + +Promise.reject(new Error("fail")).then(function(error) { + // 호출되지 않음 +}, function(error) { + console.log(error); // Stacktrace +});</pre> + +<h2 id="스펙">스펙</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">스펙</th> + <th scope="col">상태</th> + <th scope="col">설명</th> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-promise.reject', 'Promise.reject')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>ECMA 표준에서 초기 정의.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-promise.reject', 'Promise.reject')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="브라우저_호환성">브라우저 호환성</h2> + +<p class="hidden">The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p> + +<p>{{Compat("javascript.builtins.Promise.reject")}}</p> + +<p> </p> + +<h2 id="참조">참조</h2> + +<ul> + <li>{{jsxref("Promise")}}</li> + <li><a href="https://github.com/petkaantonov/bluebird#error-handling">BlueBird Promise 라이브러리를 사용해 선택된 오류 잡기</a></li> +</ul> diff --git a/files/ko/web/javascript/reference/global_objects/promise/resolve/index.html b/files/ko/web/javascript/reference/global_objects/promise/resolve/index.html new file mode 100644 index 0000000000..64180ef2bf --- /dev/null +++ b/files/ko/web/javascript/reference/global_objects/promise/resolve/index.html @@ -0,0 +1,162 @@ +--- +title: Promise.resolve() +slug: Web/JavaScript/Reference/Global_Objects/Promise/resolve +tags: + - ECMAScript6 + - JavaScript + - Method + - Promise + - 레퍼런스 +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/resolve +--- +<div>{{JSRef}}</div> + +<p><code><strong>Promise.resolve(value)</strong></code> 메서드는 주어진 값으로 이행하는 {{jsxref("Promise.then")}} 객체를 반환합니다. 그 값이 프로미스인 경우, 해당 프로미스가 반환됩니다. 그 값이 thenable(예, {{jsxref("Promise.then", "\"then\" 메소드")}} 가 있음)인 경우, 반환된 프로미스는 그 thenable을 "따르며", 그 최종 상태를 취합니다. 그렇지 않으면 반환된 프로미스는 그 값으로 이행합니다. 이 함수는 프로미스형의 객체(무언가를 결정하는 프로미스를 결정하는 프로미스 등)의 중첩된 레이어를 단일 레이어로 펼칩니다.</p> + +<div class="blockIndicator warning"> +<p><strong>주의</strong>: 스스로를 결정하는 thenable 에서 <code>Promise.resolve</code> 를 호출하면 안됩니다. 이는 무한히 중첩된 프로미스를 펼치려고하므로 무한 재귀를 유발할 것입니다. Angular 에서 <code>async</code> Pipe 를 함께 사용한 <a href="https://stackblitz.com/edit/angular-promiseresovle-with-async-pipe?file=src/app/app.component.ts">예제</a>입니다. 자세한 내용은<a href="https://angular.io/guide/template-syntax#avoid-side-effects"> 여기</a>에서 확인하세요.</p> +</div> + +<div>{{EmbedInteractiveExample("pages/js/promise-resolve.html")}}</div> + +<div class="hidden"> +<p>The source for this interactive demo is stored in a GitHub repository. If you'd like to contribute to the interactive demo project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</p> +</div> + +<h2 id="구문">구문</h2> + +<pre class="syntaxbox"><var>Promise.resolve(value)</var>; +</pre> + +<h3 id="파라미터">파라미터</h3> + +<dl> + <dt>value</dt> + <dd>이 <code>Promise</code>에 의해 결정되는 인수. <code>Promise</code> 또는 이행할 thenable 일수도 있습니다.</dd> +</dl> + +<h3 id="반환_값">반환 값</h3> + +<dl> + <dd> + <p>주어진 값으로 이행된 {{jsxref("Promise")}} 또는 값이 promise 객체인 경우, 값으로 전달된 promise. </p> + </dd> +</dl> + +<h2 id="설명">설명</h2> + +<p>정적 <code>Promise.resolve</code> 함수는 이행된 <code>Promise</code> 를 반환합니다.</p> + +<h2 id="예시">예시</h2> + +<h3 id="정적_Promise.resolve_메소드_사용">정적 <code>Promise.resolve</code> 메소드 사용</h3> + +<pre class="brush: js">Promise.resolve("Success").then(function(value) { + console.log(value); // "Success" +}, function(value) { + // 호출되지 않음 +}); +</pre> + +<h3 id="배열_이행">배열 이행</h3> + +<pre class="brush: js">var p = Promise.resolve([1,2,3]); +p.then(function(v) { + console.log(v[0]); // 1 +}); +</pre> + +<h3 id="또_다른_Promise_이행">또 다른 <code>Promise</code> 이행</h3> + +<pre class="brush: js">var original = Promise.resolve(33); +var cast = Promise.resolve(original); +cast.then(function(value) { + console.log('value: ' + value); +}); +<code>console.log('original === cast ? ' + (original === cast)); +</code> +<code>// 로그 순서: +// original === cast ? true +// value: 33</code> +</pre> + +<p>로그의 순서가 반대인 이유는 <code>then</code> 핸들러가 비동기로 호출되기 때문입니다. <a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise/then#then_%EB%A9%94%EC%84%9C%EB%93%9C_%EC%82%AC%EC%9A%A9">여기</a>에서 <code>then</code> 이 동작하는 방식에 대해 확인하세요.</p> + +<h3 id="thenable_이행_및_오류_발생">thenable 이행 및 오류 발생</h3> + +<pre class="brush: js">// thenable 객체 이행 +var p1 = Promise.resolve({ + then: function(onFulfill, onReject) { onFulfill("fulfilled!"); } +}); +console.log(p1 instanceof Promise) // true, 객체는 Promise 로 변환됨 + +p1.then(function(v) { + console.log(v); // "fulfilled!" + }, function(e) { + // 호출되지 않음 +}); + +// thenable 이 콜백 이전에 오류를 throw +// Promise 거부 +var thenable = { then: function(resolve) { + throw new TypeError("Throwing"); + resolve("Resolving"); +}}; + +var p2 = Promise.resolve(thenable); +p2.then(function(v) { + // 호출되지 않음 +}, function(e) { + console.log(e); // TypeError: Throwing +}); + +// thenable 이 콜백 이후에 오류를 throw +// Promise 이행 +var thenable = { then: function(resolve) { + resolve("Resolving"); + throw new TypeError("Throwing"); +}}; + +var p3 = Promise.resolve(thenable); +p3.then(function(v) { + console.log(v); // "Resolving" +}, function(e) { + // 호출되지 않음 +}); +</pre> + +<h2 id="명세">명세</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">명세</th> + <th scope="col">상태</th> + <th scope="col">코멘트</th> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-promise.resolve', 'Promise.resolve')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>ECMA 표준에서 초기 정의.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-promise.resolve', 'Promise.resolve')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="브라우저_호환성">브라우저 호환성</h2> + +<div class="hidden"> +<p>To contribute to this compatibility data, please write a pull request against this repository: <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a>.</p> +</div> + +<p>{{Compat("javascript.builtins.Promise.resolve")}}</p> + +<h2 id="함께_보기">함께 보기</h2> + +<ul> + <li>{{jsxref("Promise")}}</li> +</ul> diff --git a/files/ko/web/javascript/reference/global_objects/promise/then/index.html b/files/ko/web/javascript/reference/global_objects/promise/then/index.html new file mode 100644 index 0000000000..b7f79eee9c --- /dev/null +++ b/files/ko/web/javascript/reference/global_objects/promise/then/index.html @@ -0,0 +1,308 @@ +--- +title: Promise.prototype.then() +slug: Web/JavaScript/Reference/Global_Objects/Promise/then +tags: + - ECMAScript6 + - JavaScript + - Method + - Promise + - Prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/then +--- +<div>{{JSRef}}</div> + +<p><code><strong>then()</strong></code> 메서드는 {{domxref("Promise")}}를 리턴하고 두 개의 콜백 함수를 인수로 받습니다. 하나는 <code>Promise</code>가 <strong>이행</strong>했을 때, 다른 하나는 <strong>거부</strong>했을 때를 위한 콜백 함수입니다.</p> + +<div>{{EmbedInteractiveExample("pages/js/promise-then.html")}}</div> + +<p class="hidden">해당 예제의 소스 코드는 GitHub 리포지토리에 저장되어 있습니다. 인터랙티브 데모 프로젝트에 기여하고 싶다면 <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> 를 클론하고 pull request를 보내 주세요.</p> + +<div class="note"> +<p>매개변수 중 하나 이상을 생략했거나 함수가 아닌 값을 전달한 경우, <code>then</code>은 핸들러가 없는 것이 되지만 오류를 발생하지는 않습니다. <code>then</code> 바로 이전의 <code>Promise</code>가 <code>then</code>에 핸들러가 없는 상태로 완료(이행이나 거부)했을 경우, 추가 핸들러가 없는 <code>Promise</code>가 생성되며, 원래 <code>Promise</code>의 마지막 상태를 그대로 물려받습니다.</p> +</div> + +<h2 id="구문">구문</h2> + +<pre class="syntaxbox"><var>p.then(onFulfilled, onRejected)</var>; + +p.then(function(value) { + // 이행 +}, function(reason) { + // 거부 +}); +</pre> + +<h3 id="매개변수">매개변수</h3> + +<dl> + <dt><code>onFulfilled</code></dt> + <dd><code>Promise</code>가 수행될 때 호출되는 {{jsxref("Function")}}으로, <strong>이행 값(fulfillment value)</strong> 하나를 인수로 받습니다.</dd> + <dt><code>onRejected</code></dt> + <dd><code>Promise</code>가 거부될 때 호출되는 {{jsxref("Function")}}으로, <strong>거부 이유(rejection reason)</strong> 하나를 인수로 받습니다.</dd> +</dl> + +<h3 id="반환값">반환값</h3> + +<p>{{jsxref("Promise")}}가 이행하거나 거부했을 때, 각각에 해당하는 핸들러 함수(<code style="font-style: normal; font-weight: normal;">onFulfilled</code>나 <code style="font-style: normal; font-weight: normal;">onRejected</code>)가 <strong>비동기적으로</strong> 실행됩니다. 핸들러 함수는 다음 규칙을 따라 실행됩니다.</p> + +<ul> + <li>함수가 값을 반환할 경우, <code>then</code>에서 반환한 프로미스는 그 반환값을 자신의 결과값으로 하여 이행합니다.</li> + <li>값을 반환하지 않을 경우, <code>then</code>에서 반환한 프로미스는 <code>undefined</code>를 결과값으로 하여 이행합니다.</li> + <li>오류가 발생할 경우, <code>then</code>에서 반환한 프로미스는 그 오류를 자신의 결과값으로 하여 거부합니다.</li> + <li>이미 이행한 프로미스를 반환할 경우, <code>then</code>에서 반환한 프로미스는 그 프로미스의 결과값을 자신의 결과값으로 하여 이행합니다.</li> + <li>이미 거부한 프로미스를 반환할 경우, <code>then</code>에서 반환한 프로미스는 그 프로미스의 결과값을 자신의 결과값으로 하여 거부합니다.</li> + <li><strong>대기 중</strong>인 프로미스를 반환할 경우, <code>then</code>에서 반환한 프로미스는 그 프로미스의 이행 여부와 결과값을 따릅니다.</li> +</ul> + +<p>다음 예제에서 <code>then</code> 메서드의 비동기성을 확인할 수 있습니다.</p> + +<pre class="brush: js">// 이행한 프로미스를 받으면 'then' 블록도 바로 실행되지만, +// 핸들러는 아래 console.log에서와 같이 비동기적으로 실행됨 +const resolvedProm = Promise.resolve(33); + +let thenProm = resolvedProm.then(value => { + console.log("이 부분은 호출 스택 이후에 실행됩니다. 전달받은 값이자 반환값은 " + value + "입니다."); + return value; +}); +// thenProm의 값을 즉시 기록 +console.log(thenProm); + +// setTimeout으로 함수 실행을 호출 스택이 빌 때까지 미룰 수 있음 +setTimeout(() => { + console.log(thenProm); +}); + + +// 로그 출력 결과 (순서대로): +// Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined} +// "이 부분은 호출 스택 이후에 실행됩니다. 전달받은 값이자 반환값은 33입니다." +// Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 33}</pre> + +<h2 id="설명">설명</h2> + +<p><code>then</code>과 {{jsxref("Promise.prototype.catch()")}} 메서드는 프로미스를 반환하기 때문에, 체이닝이 가능합니다. 이를 <em>합성</em>이라고도 합니다.</p> + +<h2 id="예제">예제</h2> + +<h3 id="then_메서드_사용"><code>then</code> 메서드 사용</h3> + +<pre class="brush: js">var p1 = new Promise(function(resolve, reject) { + resolve("성공!"); + // 또는 + // reject("오류!"); +}); + +p1.then(function(value) { + console.log(value); // 성공! +}, function(reason) { + console.log(reason); // 오류! +}); +</pre> + +<h3 id="체이닝">체이닝</h3> + +<p><code>then</code> 메서드는 <code>Promise</code>를 리턴하기 때문에, 이어지는 <code>then</code> 호출들을 손쉽게 연결할 수 있습니다.</p> + +<p><code>then</code>에 핸들러로 전달된 함수가 프로미스를 반환할 경우, 이와 동등한 프로미스가 메서드 체인의 그다음 <code>then</code>에 노출됩니다. 아래 예제에서는 <code>setTimeout</code> 함수로 비동기 코드를 흉내냅니다.</p> + +<pre class="brush: js">Promise.resolve('foo') + // 1. "foo"를 받고 "bar"를 추가한 다음 그 값으로 이행하여 다음 then에 넘겨줌 + .then(function(string) { + return new Promise(function(resolve, reject) { + setTimeout(function() { + string += 'bar'; + resolve(string); + }, 1); + }); + }) + // 2. "foobar"를 받고 그대로 다음 then에 넘겨준 뒤, + // 나중에 콜백 함수에서 가공하고 콘솔에 출력 + .then(function(string) { + setTimeout(function() { + string += 'baz'; + console.log(string); + }, 1) + return string; + }) + // 3. 이 부분의 코드는 이전의 then 블록 안의 (가짜) 비동기 코드에서 + // 실제로 문자열을 가공하기 전에 실행됨 + .then(function(string) { + console.log("마지막 Then: 앗... 방금 then에서 프로미스 만들고 반환하는 걸 까먹어서 " + + "출력 순서가 좀 이상할지도 몰라요"); + + // 'baz' 부분은 setTimeout 함수로 비동기적으로 실행되기 때문에 + // 이곳의 string에는 아직 'baz' 부분이 없음 + console.log(string); + }); + +// 로그 출력 결과 (순서대로): +// 마지막 Then: 앗... 방금 then에서 프로미스 만들고 반환하는 걸 까먹어서 출력 순서가 좀 이상할지도 몰라요 +// foobar +// foobarbaz</pre> + +<p><code>then</code> 핸들러에서 값을 그대로 반환한 경우에는 <code>Promise.resolve(<핸들러에서 반환한 값>)</code>을 반환하는 것과 같습니다.</p> + +<pre class="brush: js">var p2 = new Promise(function(resolve, reject) { + resolve(1); +}); + +p2.then(function(value) { + console.log(value); // 1 + return value + 1; +}).then(function(value) { + console.log(value + ' - 동기적으로 짜도 돌아감'); +}); + +p2.then(function(value) { + console.log(value); // 1 +}); +</pre> + +<p>함수에서 오류가 발생하거나 거부한 프로미스를 반환한 경우 <code>then</code>에서는 거부한 프로미스를 반환합니다.</p> + +<pre class="brush: js">Promise.resolve() + .then(() => { + // .then()에서 거부한 프로미스를 반환함 + throw new Error('으악!'); + }) + .then(() => { + console.log('실행되지 않는 코드'); + }, error => { + console.error('onRejected 함수가 실행됨: ' + error.message); + });</pre> + +<p>이외의 모든 경우에는 곧 이행할(비동기적으로 실행되는) 프로미스를 반환합니다. 다음 예제에서는 바로 이전의 프로미스가 거부했음에도 첫 번째 <code>then</code>에서는 <code>42</code>의 값을 갖는 곧 이행할 프로미스를 반환합니다.</p> + +<pre class="brush: js">Promise.reject() + .then(() => 99, () => 42) // onRejected에서는 42를 곧 이행할 프로미스로 감싸서 반환함 + .then(solution => console.log(solution + '로 이행함')); // 42로 이행함</pre> + +<p>실제 개발 시에는 아래와 같이 거부한 프로미스를 <code>then</code>의 2단 핸들러보다는 <code>catch</code>를 사용해 처리하는 경우가 많습니다.</p> + +<pre class="brush: js">Promise.resolve() + .then(() => { + // .then()에서 거부한 프로미스를 반환함 + throw new Error('으악!'); + }) + .catch(error => { + console.error('onRejected 함수가 실행됨: ' + error.message); + }) + .then(() => { + console.log("처음 then의 프로미스가 거부했지만 그래도 이 코드는 실행됨"); + });</pre> + +<p><br> + 체이닝을 이용해 프로미스 기반 함수 위에 다른 프로미스 기반 함수를 구현할 수도 있습니다.</p> + +<pre class="brush: js">function fetch_current_data() { + // fetch() API는 프로미스를 반환합니다. 이 함수도 + // API가 비슷하지만, 이 함수의 프로미스는 + // 추가 작업을 거친 이후에 이행값을 반환합니다. + return fetch('current-data.json').then(response => { + if (response.headers.get('content-type') != 'application/json') { + throw new TypeError(); + } + var j = response.json(); + // j 가공하기 + return j; // fetch_current_data().then()을 통해 + // 이행값을 사용할 수 있음 + }); +} +</pre> + +<p><code>onFulfilled</code>가 프로미스를 반환할 경우, <code>then</code>의 반환값 역시 그 프로미스에 의해 이행/거부합니다.</p> + +<pre class="brush: js">function resolveLater(resolve, reject) { + setTimeout(function() { + resolve(10); + }, 1000); +} +function rejectLater(resolve, reject) { + setTimeout(function() { + reject(new Error('오류')); + }, 1000); +} + +var p1 = Promise.resolve('foo'); +var p2 = p1.then(function() { + // 1초 뒤에 10으로 이행할 프로미스 반환 + return new Promise(resolveLater); +}); +p2.then(function(v) { + console.log('이행', v); // "이행", 10 +}, function(e) { + // 실행되지 않음 + console.log('거부', e); +}); + +var p3 = p1.then(function() { + // 1초 뒤에 '오류'로 거부할 프로미스 반환 + return new Promise(rejectLater); +}); +p3.then(function(v) { + // 실행되지 않음 + console.log('이행', v); +}, function(e) { + console.log('거부', e); // "거부", '오류' +}); +</pre> + +<h3 id="domxref(window.setImmediate)의_프로미스_기반_폴리필">{{domxref("window.setImmediate")}}의 프로미스 기반 폴리필</h3> + +<p>{{jsxref("Function.prototype.bind()")}} <code>Reflect.apply</code> ({{jsxref("Reflect.apply()")}}) 메서드를 사용하여 (취소할 수 없는) setImmedate와 비슷한 함수를 생성합니다.</p> + +<pre class="brush: js">const nextTick = (() => { + const noop = () => {}; // literally + const nextTickPromise = () => Promise.resolve().then(noop); + + const rfab = Reflect.apply.bind; // (thisArg, fn, thisArg, [...args]) + const nextTick = (fn, ...args) => ( + fn !== undefined + ? Promise.resolve(args).then(rfab(null, fn, null)) + : nextTickPromise(), + undefined + ); + nextTick.ntp = nextTickPromise; + + return nextTick; +})(); +</pre> + +<h2 id="스펙">스펙</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">스펙</th> + <th scope="col">상태</th> + <th scope="col">설명</th> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-promise.prototype.then', 'Promise.prototype.then')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>ECMA 표준에서 초기 정의.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-promise.prototype.then', 'Promise.prototype.then')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="브라우저_호환성">브라우저 호환성</h2> + + + +<p class="hidden">The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p> + +<p>{{Compat("javascript.builtins.Promise.then")}}</p> + + + +<h2 id="참조">참조</h2> + +<ul> + <li>{{jsxref("Promise")}}</li> + <li>{{jsxref("Promise.prototype.catch()")}}</li> +</ul> |