From da78a9e329e272dedb2400b79a3bdeebff387d47 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:42:17 -0500 Subject: initial commit --- .../global_objects/promise/all/index.html | 239 ++++++++++++++++ .../global_objects/promise/allsettled/index.html | 66 +++++ .../global_objects/promise/finally/index.html | 100 +++++++ .../reference/global_objects/promise/index.html | 226 +++++++++++++++ .../global_objects/promise/promise/index.html | 78 ++++++ .../global_objects/promise/prototype/index.html | 71 +++++ .../global_objects/promise/race/index.html | 187 +++++++++++++ .../global_objects/promise/reject/index.html | 81 ++++++ .../global_objects/promise/resolve/index.html | 162 +++++++++++ .../global_objects/promise/then/index.html | 308 +++++++++++++++++++++ 10 files changed, 1518 insertions(+) create mode 100644 files/ko/web/javascript/reference/global_objects/promise/all/index.html create mode 100644 files/ko/web/javascript/reference/global_objects/promise/allsettled/index.html create mode 100644 files/ko/web/javascript/reference/global_objects/promise/finally/index.html create mode 100644 files/ko/web/javascript/reference/global_objects/promise/index.html create mode 100644 files/ko/web/javascript/reference/global_objects/promise/promise/index.html create mode 100644 files/ko/web/javascript/reference/global_objects/promise/prototype/index.html create mode 100644 files/ko/web/javascript/reference/global_objects/promise/race/index.html create mode 100644 files/ko/web/javascript/reference/global_objects/promise/reject/index.html create mode 100644 files/ko/web/javascript/reference/global_objects/promise/resolve/index.html create mode 100644 files/ko/web/javascript/reference/global_objects/promise/then/index.html (limited to 'files/ko/web/javascript/reference/global_objects/promise') 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 +--- +
{{JSRef}}
+ +

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

+ +
{{EmbedInteractiveExample("pages/js/promise-all.html")}}
+ + + +

구문

+ +
Promise.all(iterable);
+
+ +

매개변수

+ +
+
iterable
+
{{jsxref("Array")}}와 같이 순회 가능한(iterable) 객체.
+
+ +

반환 값

+ + + +

설명

+ +

Promise.all은 여러 프로미스의 결과를 집계할 때 유용하게 사용할 수 있습니다.

+ +

이행

+ +

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

+ + + +

거부

+ +

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

+ +

예제

+ +

Promise.all 사용하기

+ +

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

+ +
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"]
+});
+ +

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

+ +
// 매개변수 배열이 빈 것과 동일하게 취급하므로 이행함
+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 }
+ +

Promise.all의 동기성/비동기성

+ +

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

+ +
// 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] }
+
+ +

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

+ +
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 }
+
+ +

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

+ +
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] }
+
+ +

Promise.all() 실패 우선성

+ +

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

+ +
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)
+});
+
+// 콘솔 출력값:
+// "거부"
+
+ +

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

+ +
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_즉시_거부"
+})
+
+ +

명세

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-promise.all', 'Promise.all')}}{{Spec2('ES2015')}}Initial definition in an ECMA standard.
{{SpecName('ESDraft', '#sec-promise.all', 'Promise.all')}}{{Spec2('ESDraft')}}
+ +

브라우저 호환성

+ + + +

{{Compat("javascript.builtins.Promise.all")}}

+ +

같이 보기

+ + 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 +--- +

{{JSRef}}

+ +

Promise.allSettled() 메소드는 배열이나 별도의 나열 가능한 객체를 통해 나열된 Promise모음이 모두 이행하거나 거부했을 때에 대한 대응을 할 수 있는 Promise 객체를 반환한다.

+ +
{{EmbedInteractiveExample("pages/js/promise-allsettled.html")}}
+ +

문법

+ +
Promise.allSettled(iterable);
+ +

인자

+ +
+
iterable
+
iterable 객체로, 주로 배열({{jsxref("Array")}})을 사용하며, 이들의 요소들은 모두 Promise 객체.
+
+ +

반환 값

+ +

실행할 {{jsxref("Promise")}} 객체로 비동기 방식으로 이행(Resolved) 및 거부(Rejected)된 결과의 모음을 담아 인자로 전달된다. 이 때 반환된 Promise 객체의 핸들러는 각 본래 Promise 객체가 담긴 배열을 전달할 것이다.

+ +

각 출력 객체는 status 속성을 통해,  fulfilled,상태로 전달되면 value 속성이 전달되고, rejected 상태로 전달 시 reason 속성으로 전달된다. 각 Promise가 어떻게 이행(또는 거부)됐는지 value 속성 및 reason 속성을 통해 알 수 있다.

+ +

문서 표준

+ + + + + + + + + + + + + + +
SpecificationStatusComment
Promise.allSettled() (TC39 Stage 4 Draft){{Spec2('ESDraft')}}
+ +

지원 브라우저

+ + + +

{{Compat("javascript.builtins.Promise.allSettled")}}

+ +

구현 진행 상태

+ +

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 Test262, the standard test suite of JavaScript, in the nightly build, or latest release of each browser's JavaScript engine.

+ +
{{EmbedTest262ReportResultsTable("Promise.allSettled")}}
+ +

같이 보기

+ + 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 +--- +
{{JSRef}}
+ +

finally() 메소드는 {{jsxref("Promise")}} 객체를 반환합니다. Promise가 처리되면 충족되거나 거부되는지 여부에 관계없이 지정된 콜백 함수가 실행됩니다. 이것은 Promise가 성공적으로 수행 되었는지 거절되었는지에 관계없이 Promise가 처리 된 후에 코드가 무조건 한 번은 실행되는 것을 제공합니다.

+ +

이것은 Promise의 {{jsxref("Promise.then", "then()")}}과 {{jsxref("Promise.catch", "catch()")}} 핸들러에서의 코드 중복을 피하게 합니다.

+ +

문법

+ +
p.finally(onFinally);
+
+p.finally(function() {
+   // settled (fulfilled or rejected)
+});
+
+ +

Parameters

+ +
+
onFinally
+
Promise가 처리된 후 {{jsxref("Function")}} 이 호출됩니다.
+
+ +

Return value

+ +

finally 핸들러는 onFinally 라는 지정된 함수의 {{jsxref("Promise")}}가 반환됩니다.

+ +

설명

+ +

 

+ +

finally() 메서드는 결과에 관계없이 promise가 처리되면 무언가를 프로세싱 또는 정리를 수행하려는 경우에 유용합니다.

+ +

finally() 메서드는 .then(onFinally, onFinally) 를 호출하는 것과 매우 비슷하지만 몇 가지 차이점이 있습니다:

+ +

 

+ + + +
+

Note:  finally 콜백에서 throw (또는 거부된 promise를 반환)하면 throw()를 호출 할 때 지정된 거부 이유로 새롭게 만들어진 promise를 반환합니다.

+
+ +

예제

+ +
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; });
+
+
+ +

명세

+ + + + + + + + + + + + + + +
SpecificationStatusComment
TC39 proposalStage 4 
+ +

브라우저 호환성

+ + + +

{{Compat("javascript.builtins.Promise.finally")}}

+ +

더보기

+ + 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 +--- +
{{JSRef}}
+ +

Promise 객체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타냅니다.

+ +

Promise의 작동 방식과 Promise 사용 방법에 대해 알아보려면 먼저 Promise 사용 방법을 읽어 보십시오.

+ +

설명

+ +

Promise는 프로미스가 생성될 때 꼭 알 수 있지는 않은 값을 위한 대리자로, 비동기 연산이 종료된 이후의 결과값이나 실패 이유를 처리하기 위한 처리기를 연결할 수 있도록 합니다. 프로미스를 사용하면 비동기 메서드에서 마치 동기 메서드처럼 값을 반환할 수 있습니다. 다만 최종 결과를 반환하지는 않고, 대신 프로미스를 반환해서 미래의 어떤 시점에 결과를 제공합니다.

+ +

Promise는 다음 중 하나의 상태를 가집니다.

+ + + +

대기 중인 프로미스는 값과 함께 이행할 수도, 어떤 이유(오류)로 인해 거부될 수 있습니다. 이행이나 거부될 때, 프로미스에 연결한 처리기는 그 프로미스의 then 메서드에 의해 대기열에 오릅니다. 이미 이행했거나 거부된 프로미스에 연결한 처리기도 호출하므로, 비동기 연산과 처리기 연결 사이에 경합 조건race condition은 없습니다.

+ +

{{jsxref("Promise.prototype.then()")}} 및 {{jsxref("Promise.prototype.catch()")}} 메서드의 반환 값은 다른 프로미스이므로, 서로 연결할 수 있습니다.

+ +

+ +
+

혼동 주의: 느긋한 계산법 및 연산 연기를 위한 방법을 프로미스라고 부르는 다른 언어(예: Scheme)가 여럿 있습니다. 반면 JavaScript에서 프로미스는 콜백 함수를 연결할 수 있는 이미 진행 중인 프로세스를 나타냅니다. 표현식을 느긋하게 평가하려면 인수 없는 화살표 함수 f = () => expression를 사용하고, f()를 사용해 평가하세요.

+
+ +
+

참고: 프로미스는 대기 중이지 않으며 이행 또는 거부됐을 때 처리(settled)됐다고 말합니다. 프로미스와 함께 쓰이는 단어 resolved는 프로미스가 다른 프로미스의 상태에 맞춰 처리됨, 또는 상태가 "잠김"되었다는 의미입니다. 용어에 관한 더 자세한 설명은 Domenic Denicola의 글 States and fates에서 볼 수 있습니다.

+
+ +

생성자

+ +
+
{{jsxref("Promise.Promise", "Promise()")}}
+
이미 프로미스를 지원하지 않는 함수를 감쌀 때 주로 사용합니다.
+
+ +

속성

+ +
+
Promise.length
+
값이 언제나 1인 길이 속성입니다. (생성자 인수의 수)
+
{{jsxref("Promise.prototype")}}
+
Promise 생성자의 프로토타입을 나타냅니다.
+
+ +

메서드

+ +
+
{{jsxref("Promise.all", "Promise.all(iterable)")}}
+
iterable 내의 모든 프로미스가 이행한 뒤 이행하고, 어떤 프로미스가 거부하면 즉시 거부하는 프로미스를 반환합니다. 반환된 프로미스가 이행하는 경우 iterable 내의 프로미스가 결정한 값을 모은 배열이 이행 값입니다. 반환된 프로미스가 거부하는 경우 iterable 내의 거부한 프로미스의 이유를 그대로 사용합니다. 이 메서드는 여러 프로미스의 결과를 모을 때 유용합니다.
+
{{jsxref("Promise.race", "Promise.race(iterable)")}}
+
iterable 내의 어떤 프로미스가 이행하거나 거부하는 즉시 스스로 이행하거나 거부하는 프로미스를 반환합니다. 이행 값이나 거부 이유는 원 프로미스의 값이나 이유를 그대로 사용합니다.
+
+ +
+
{{jsxref("Promise.reject()")}}
+
주어진 이유로 거부하는 Promise 객체를 반환합니다.
+
+ +
+
{{jsxref("Promise.resolve()")}}
+
주어진 값으로 이행하는 Promise 객체를 반환합니다. 값이 then 가능한 (즉, then 메서드가 있는) 경우, 반환된 프로미스는 then 메서드를 따라가고 마지막 상태를 취합니다. 그렇지 않은 경우 반환된 프로미스는 주어진 값으로 이행합니다. 어떤 값이 프로미스인지 아닌지 알 수 없는 경우, {{jsxref("Promise.resolve", "Promise.resolve(value)")}} 후 반환값을 프로미스로 처리할 수 있습니다.
+
+ +

Promise 프로토타입

+ +

속성

+ +

{{page('ko/docs/Web/JavaScript/Reference/Global_Objects/Promise/prototype','속성')}}

+ +

메서드

+ +

{{page('ko/docs/Web/JavaScript/Reference/Global_Objects/Promise/prototype','메서드')}}

+ +

예제

+ +

기본 예제

+ +
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);
+});
+ +

고급 예제

+ + + +

다음의 작은 예제는 Promise의 동작 방식을 보여줍니다. testPromise() 함수는 {{HTMLElement("button")}}을 클릭할 때마다 호출되며, {{domxref("window.setTimeout()")}}을 사용해 1~3초의 무작위 간격 이후 프로미스 횟수(1부터 시작하는 숫자)로 이행하는 프로미스를 생성합니다. Promise() 생성자는 프로미스를 만드는 데 쓰입니다.

+ +

프로미스 이행은 {{jsxref("Promise.prototype.then()","p1.then()")}}을 사용하는 이행 콜백 세트를 통해 단순히 로그에 남습니다. 약간의 로그를 통해, 함수의 동기 부분이 비동기적 프로미스의 완료와 어떻게 분리되어 있는지 확인할 수 있습니다.

+ +
'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/>');
+}
+
+ + + +

이 예제는 버튼을 클릭하면 실행됩니다. Promise를 지원하는 브라우저가 필요합니다. 짧은 시간 안에 버튼을 여러 번 클릭하여, 서로 다른 프로미스가 번갈아 이행되는 것을 볼 수도 있습니다.

+ +

{{EmbedLiveSample("고급_예제", "500", "200")}}

+ +

XHR로 이미지 불러오기

+ +

이미지를 로드하기 위해 Promise 및 {{domxref("XMLHttpRequest")}}를 사용하는 또 다른 간단한 예는 MDN GitHub js-examples 저장소에서 이용할 수 있습니다. 실제 예를 볼 수도 있습니다. 각 단계에 주석이 붙어있어, 프로미스 및 XHR 구조를 차근차근 따라갈 수 있습니다.

+ +

명세

+ + + + + + + + + + + + + + + + + + + +
명세상태설명
{{SpecName('ES6', '#sec-promise-objects', 'Promise')}}{{Spec2('ES6')}}ECMA 표준에서 초기 정의.
{{SpecName('ESDraft', '#sec-promise-objects', 'Promise')}}{{Spec2('ESDraft')}}
+ +

브라우저 호환성

+ +
+ + +

{{Compat("javascript.builtins.Promise")}}

+
+ +

같이 보기

+ + 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 +--- +
{{JSRef}}
+ +

Promise 생성자는 주로 프로미스를 지원하지 않는 함수를 감쌀 때 사용합니다.

+ +
{{EmbedInteractiveExample("pages/js/promise-constructor.html")}}
+ + + +

구문

+ +
new Promise(executor)
+ +

매개변수

+ +
+
executor
+
resolvereject 인수를 전달할 실행 함수. 실행 함수는 프로미스 구현에 의해 resolvereject 함수를 받아 즉시 실행됩니다(실행 함수는 Promise 생성자가 생성한 객체를 반환하기도 전에 호출됩니다). resolvereject 함수는 호출할 때 각각 프로미스를 이행하거나 거부합니다. 실행 함수는 보통 어떤 비동기 작업을 시작한 후 모든 작업을 끝내면 resolve를 호출해 프로미스를 이행하고, 오류가 발생한 경우 reject를 호출해 거부합니다. 실행 함수에서 오류를 던지면 프로미스는 거부됩니다. 실행 함수의 반환값은 무시됩니다.
+
+ +

예제

+ +

Promise 객체는 new 키워드와 생성자를 사용해 만듭니다. 생성자는 매개변수로 "실행 함수"를 받습니다. 이 함수는 매개 변수로 두 가지 함수를 받아야 하는데, 첫 번째 함수(resolve)는 비동기 작업을 성공적으로 완료해 결과를 값으로 반환할 때 호출해야 하고, 두 번째 함수(reject)는 작업이 실패하여 오류의 원인을 반환할 때 호출하면 됩니다. 두 번째 함수는 주로 오류 객체를 받습니다.

+ +
const myFirstPromise = new Promise((resolve, reject) => {
+  // do something asynchronous which eventually calls either:
+  //
+  //   resolve(someValue)        // fulfilled
+  // or
+  //   reject("failure reason")  // rejected
+});
+
+ +

함수에 프로미스 기능을 추가하려면, 간단하게 프로미스를 반환하도록 하면 됩니다.

+ +
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()
+  });
+}
+ +

명세

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-promise-constructor', 'Promise constructor')}}
+ +

브라우저 호환성

+ + + +

{{Compat("javascript.builtins.Promise.Promise")}}

+ +

같이 보기

+ + 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 +--- +
{{JSRef}}
+ +

Promise.prototype 속성은 {{jsxref("Promise")}} 생성자의 프로토타입을 나타냅니다.

+ +
{{js_property_attributes(0,0,0)}}
+ +

설명

+ +

{{jsxref("Promise")}} 인스턴스는 {{jsxref("Promise.prototype")}}을 상속합니다. 모든 Promise 인스턴스에 속성 또는 메서드를 추가하기 위해 생성자의 프로토타입 객체를 사용할 수 있습니다.

+ +

속성

+ +
+
Promise.prototype.constructor
+
인스턴스의 프로토타입을 만드는 함수를 반환합니다. 기본값은 {{jsxref("Promise")}} 함수입니다.
+
+ +

메서드

+ +
+
{{jsxref("Promise.prototype.catch()")}}
+
프로미스(promise)에 거부 처리기 콜백을 추가하고 호출된 경우 콜백의 반환값 또는 프로미스가 대신 이행된 경우 그 원래 이행(fulfillment)값으로 결정하는(resolving) 새 프로미스를 반환합니다.
+
{{jsxref("Promise.prototype.then()")}}
+
프로미스에 이행 또는 거부 처리기를 추가하고 호출된 처리기의 반환값 또는 프로미스가 처리되지 않은 경우 그 원래 처리된(settled) 값으로 결정하는 새 프로미스를 반환합니다 (즉 관련 처리기 onFulfilled 또는 onRejectedundefined인 경우).
+
{{jsxref("Promise.prototype.finally()")}}
+
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.
+
+ +

명세

+ + + + + + + + + + + + + + + + + + + +
명세상태설명
{{SpecName('ES6', '#sec-promise.prototype', 'Promise.prototype')}}{{Spec2('ES6')}}초기 정의.
{{SpecName('ESDraft', '#sec-promise.prototype', 'Promise.prototype')}}{{Spec2('ESDraft')}} 
+ +

브라우저 호환성

+ + + +

{{Compat("javascript.builtins.Promise.prototype")}}

+ +

같이 보기

+ + 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 +--- +
{{JSRef}}
+ +

Promise.race() 메소드는 Promise 객체를 반환합니다. 이 프로미스 객체는 iterable 안에 있는 프로미스 중에 가장 먼저 완료된 것의 결과값으로 그대로 이행하거나 거부합니다.

+ +
{{EmbedInteractiveExample("pages/js/promise-race.html")}}
+ + + +

구문

+ +
Promise.race(iterable);
+ +

매개변수

+ +
+
iterable
+
{{jsxref("Array")}}와 같은 iterable 객체. iterable을 참고하세요.
+
+ +

반환값

+ +

주어진 iterable에서 처음으로 이행하거나 거부한 프로미스의 값을 비동기적으로 전달받는 대기 중인 {{jsxref("Promise")}}.

+ +

설명

+ +

race 함수는 인자로 주어진 iterable의 프로미스 중 가장 먼저 완료(settle)되는 것과 같은 방식으로 완료(이행/거부)되고, 같은 결과값을 전달하는 Promise를 반환합니다.

+ +

전달받은 iterable이 비어 있을 경우, 반환한 프로미스는 영원히 대기 상태가 됩니다.

+ +

Iterable에 프로미스가 아닌 값이나 이미 완료된 프로미스가 포함되어 있을 경우, Promise.race는 전달받은 iterable에서 처음으로 등장하는 이러한 값을 결과값으로 이행합니다.

+ +

예제

+ +

Promise.race의 비동기성

+ +

다음 예제에서 Promise.race의 비동기성을 확인할 수 있습니다.

+ +
// 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 }
+ +

비어 있는 iterable을 전달하면 반환한 프로미스는 영원히 대기 상태가 됩니다.

+ +
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" }
+
+ +

Iterable에 프로미스가 아닌 값이나 이미 완료된 프로미스가 포함되어 있을 경우, Promise.race는 전달받은 iterable에서 처음으로 등장하는 이러한 값을 결과값으로 이행합니다.

+ +
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>: "프로미스 아님" }
+
+ +

setTimeout과 함께 Promise.race 사용 예

+ +
var p1 = new Promise(function(resolve, reject) {
+    setTimeout(() => resolve('하나'), 500);
+});
+var p2 = new Promise(function(resolve, reject) {
+    setTimeout(() => resolve('둘'), 100);
+});
+
+Promise.race([p1, p2])
+.then(function(value) {
+  console.log(value); // "둘"
+  // 둘 다 이행하지만 p2가 더 빠르므로
+});
+
+var p3 = new Promise(function(resolve, reject) {
+    setTimeout(() => resolve('셋'), 100);
+});
+var p4 = new Promise(function(resolve, reject) {
+    setTimeout(() => reject(new Error('넷')), 500);
+});
+
+Promise.race([p3, p4])
+.then(function(value) {
+  console.log(value); // "셋"
+  // p3이 더 빠르므로 이행함
+}, function(reason) {
+  // 실행되지 않음
+});
+
+var p5 = new Promise(function(resolve, reject) {
+    setTimeout(() => resolve('다섯'), 500);
+});
+var p6 = new Promise(function(resolve, reject) {
+    setTimeout(() => reject(new Error('여섯')), 100);
+});
+
+Promise.race([p5, p6])
+.then(function(value) {
+  // 실행되지 않음
+}, function(error) {
+  console.log(error.message); // "여섯"
+  // p6이 더 빠르므로 거부함
+});
+ +

명세

+ + + + + + + + + + + + + + + + + + + +
명세상태설명
{{SpecName('ES6', '#sec-promise.race', 'Promise.race')}}{{Spec2('ES6')}}ECMA 표준에서 초기 정의.
{{SpecName('ESDraft', '#sec-promise.race', 'Promise.race')}}{{Spec2('ESDraft')}}
+ +

브라우저 호환성

+ + + +

{{Compat("javascript.builtins.Promise.race")}}

+ +

같이 보기

+ + 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 +--- +
{{JSRef}}
+ +

Promise.reject(reason) 메서드는 주어진 이유(reason)로 거부된 Promise 객체를 반환합니다.

+ +

구문

+ +
Promise.reject(reason);
+ +

매개변수

+ +
+
reason
+
Promise를 거부한 이유.
+
+ +

설명

+ +

정적 Promise.reject 함수는 거부된 Promise를 반환합니다. 디버깅 목적 및 선택된 오류를 잡기 위해, reasoninstanceof {{jsxref("Error")}} 이게 하는데 유용합니다.

+ +

+ +

정적 Promise.reject() 메서드 사용

+ +
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
+});
+ +

스펙

+ + + + + + + + + + + + + + + + + + + +
스펙상태설명
{{SpecName('ES6', '#sec-promise.reject', 'Promise.reject')}}{{Spec2('ES6')}}ECMA 표준에서 초기 정의.
{{SpecName('ESDraft', '#sec-promise.reject', 'Promise.reject')}}{{Spec2('ESDraft')}} 
+ +

브라우저 호환성

+ + + +

{{Compat("javascript.builtins.Promise.reject")}}

+ +

 

+ +

참조

+ + 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 +--- +
{{JSRef}}
+ +

Promise.resolve(value) 메서드는 주어진 값으로 이행하는 {{jsxref("Promise.then")}} 객체를 반환합니다. 그 값이 프로미스인 경우, 해당 프로미스가 반환됩니다. 그 값이 thenable(예, {{jsxref("Promise.then", "\"then\" 메소드")}} 가 있음)인 경우, 반환된 프로미스는 그 thenable을 "따르며", 그 최종 상태를 취합니다. 그렇지 않으면 반환된 프로미스는 그 값으로 이행합니다. 이 함수는 프로미스형의 객체(무언가를 결정하는 프로미스를 결정하는 프로미스 등)의 중첩된 레이어를 단일 레이어로 펼칩니다.

+ +
+

주의: 스스로를 결정하는 thenable 에서 Promise.resolve 를 호출하면 안됩니다. 이는 무한히 중첩된 프로미스를 펼치려고하므로 무한 재귀를 유발할 것입니다. Angular 에서 async Pipe 를 함께 사용한 예제입니다. 자세한 내용은 여기에서 확인하세요.

+
+ +
{{EmbedInteractiveExample("pages/js/promise-resolve.html")}}
+ + + +

구문

+ +
Promise.resolve(value);
+
+ +

파라미터

+ +
+
value
+
Promise에 의해 결정되는 인수. Promise 또는 이행할 thenable 일수도 있습니다.
+
+ +

반환 값

+ +
+
+

주어진 값으로 이행된 {{jsxref("Promise")}} 또는 값이 promise 객체인 경우, 값으로 전달된 promise. 

+
+
+ +

설명

+ +

정적 Promise.resolve 함수는 이행된 Promise 를 반환합니다.

+ +

예시

+ +

정적 Promise.resolve 메소드 사용

+ +
Promise.resolve("Success").then(function(value) {
+  console.log(value); // "Success"
+}, function(value) {
+  // 호출되지 않음
+});
+
+ +

배열 이행

+ +
var p = Promise.resolve([1,2,3]);
+p.then(function(v) {
+  console.log(v[0]); // 1
+});
+
+ +

또 다른 Promise 이행

+ +
var original = Promise.resolve(33);
+var cast = Promise.resolve(original);
+cast.then(function(value) {
+  console.log('value: ' + value);
+});
+console.log('original === cast ? ' + (original === cast));
+
+// 로그 순서:
+// original === cast ? true
+// value: 33
+
+ +

로그의 순서가 반대인 이유는 then 핸들러가 비동기로 호출되기 때문입니다. 여기에서 then 이 동작하는 방식에 대해 확인하세요.

+ +

thenable 이행 및 오류 발생

+ +
// 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) {
+  // 호출되지 않음
+});
+
+ +

명세

+ + + + + + + + + + + + + + + + + + + +
명세상태코멘트
{{SpecName('ES6', '#sec-promise.resolve', 'Promise.resolve')}}{{Spec2('ES6')}}ECMA 표준에서 초기 정의.
{{SpecName('ESDraft', '#sec-promise.resolve', 'Promise.resolve')}}{{Spec2('ESDraft')}} 
+ +

브라우저 호환성

+ + + +

{{Compat("javascript.builtins.Promise.resolve")}}

+ +

함께 보기

+ + 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 +--- +
{{JSRef}}
+ +

then() 메서드는 {{domxref("Promise")}}를 리턴하고 두 개의 콜백 함수를 인수로 받습니다. 하나는 Promise이행했을 때, 다른 하나는 거부했을 때를 위한 콜백 함수입니다.

+ +
{{EmbedInteractiveExample("pages/js/promise-then.html")}}
+ + + +
+

매개변수 중 하나 이상을 생략했거나 함수가 아닌 값을 전달한 경우, then은 핸들러가 없는 것이 되지만 오류를 발생하지는 않습니다. then 바로 이전의 Promisethen에 핸들러가 없는 상태로 완료(이행이나 거부)했을 경우, 추가 핸들러가 없는 Promise가 생성되며, 원래 Promise의 마지막 상태를 그대로 물려받습니다.

+
+ +

구문

+ +
p.then(onFulfilled, onRejected);
+
+p.then(function(value) {
+  // 이행
+}, function(reason) {
+  // 거부
+});
+
+ +

매개변수

+ +
+
onFulfilled
+
Promise가 수행될 때 호출되는 {{jsxref("Function")}}으로, 이행 값(fulfillment value) 하나를 인수로 받습니다.
+
onRejected
+
Promise가 거부될 때 호출되는 {{jsxref("Function")}}으로, 거부 이유(rejection reason) 하나를 인수로 받습니다.
+
+ +

반환값

+ +

{{jsxref("Promise")}}가 이행하거나 거부했을 때, 각각에 해당하는 핸들러 함수(onFulfilledonRejected)가 비동기적으로 실행됩니다. 핸들러 함수는 다음 규칙을 따라 실행됩니다.

+ + + +

다음 예제에서 then 메서드의 비동기성을 확인할 수 있습니다.

+ +
// 이행한 프로미스를 받으면 '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}
+ +

설명

+ +

then과 {{jsxref("Promise.prototype.catch()")}} 메서드는 프로미스를 반환하기 때문에, 체이닝이 가능합니다. 이를 합성이라고도 합니다.

+ +

예제

+ +

then 메서드 사용

+ +
var p1 = new Promise(function(resolve, reject) {
+  resolve("성공!");
+  // 또는
+  // reject("오류!");
+});
+
+p1.then(function(value) {
+  console.log(value); // 성공!
+}, function(reason) {
+  console.log(reason); // 오류!
+});
+
+ +

체이닝

+ +

then 메서드는 Promise를 리턴하기 때문에, 이어지는 then 호출들을 손쉽게 연결할 수 있습니다.

+ +

then에 핸들러로 전달된 함수가 프로미스를 반환할 경우, 이와 동등한 프로미스가 메서드 체인의 그다음 then에 노출됩니다. 아래 예제에서는 setTimeout 함수로 비동기 코드를 흉내냅니다.

+ +
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
+ +

then 핸들러에서 값을 그대로 반환한 경우에는 Promise.resolve(<핸들러에서 반환한 값>)을 반환하는 것과 같습니다.

+ +
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
+});
+
+ +

함수에서 오류가 발생하거나 거부한 프로미스를 반환한 경우 then에서는 거부한 프로미스를 반환합니다.

+ +
Promise.resolve()
+  .then(() => {
+    // .then()에서 거부한 프로미스를 반환함
+    throw new Error('으악!');
+  })
+  .then(() => {
+    console.log('실행되지 않는 코드');
+  }, error => {
+    console.error('onRejected 함수가 실행됨: ' + error.message);
+  });
+ +

이외의 모든 경우에는 곧 이행할(비동기적으로 실행되는) 프로미스를 반환합니다. 다음 예제에서는 바로 이전의 프로미스가 거부했음에도 첫 번째 then에서는 42의 값을 갖는 곧 이행할 프로미스를 반환합니다.

+ +
Promise.reject()
+  .then(() => 99, () => 42) // onRejected에서는 42를 곧 이행할 프로미스로 감싸서 반환함
+  .then(solution => console.log(solution + '로 이행함')); // 42로 이행함
+ +

실제 개발 시에는 아래와 같이 거부한 프로미스를 then의 2단 핸들러보다는 catch를 사용해 처리하는 경우가 많습니다.

+ +
Promise.resolve()
+  .then(() => {
+    // .then()에서 거부한 프로미스를 반환함
+    throw new Error('으악!');
+  })
+  .catch(error => {
+    console.error('onRejected 함수가 실행됨: ' + error.message);
+  })
+  .then(() => {
+    console.log("처음 then의 프로미스가 거부했지만 그래도 이 코드는 실행됨");
+  });
+ +


+ 체이닝을 이용해 프로미스 기반 함수 위에 다른 프로미스 기반 함수를 구현할 수도 있습니다.

+ +
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()을 통해
+              // 이행값을 사용할 수 있음
+  });
+}
+
+ +

onFulfilled가 프로미스를 반환할 경우, then의 반환값 역시 그 프로미스에 의해 이행/거부합니다.

+ +
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); // "거부", '오류'
+});
+
+ +

{{domxref("window.setImmediate")}}의 프로미스 기반 폴리필

+ +

{{jsxref("Function.prototype.bind()")}} Reflect.apply ({{jsxref("Reflect.apply()")}}) 메서드를 사용하여 (취소할 수 없는) setImmedate와 비슷한 함수를 생성합니다.

+ +
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;
+})();
+
+ +

스펙

+ + + + + + + + + + + + + + + + + + + +
스펙상태설명
{{SpecName('ES6', '#sec-promise.prototype.then', 'Promise.prototype.then')}}{{Spec2('ES6')}}ECMA 표준에서 초기 정의.
{{SpecName('ESDraft', '#sec-promise.prototype.then', 'Promise.prototype.then')}}{{Spec2('ESDraft')}}
+ +

브라우저 호환성

+ + + + + +

{{Compat("javascript.builtins.Promise.then")}}

+ + + +

참조

+ + -- cgit v1.2.3-54-g00ecf