Javascript Promise
Promise
Promise 객체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타냅니다.
Promise
는 다음 중 하나의 상태를 가집니다.
- 대기(pending): 이행하거나 거부되지 않은 초기 상태.
- 이행(fulfilled): 연산이 성공적으로 완료됨.
- 거부(rejected): 연산이 실패함.
생성자
- Promise()
이미 프로미스를 지원하지 않는 함수를 감쌀 때 주로 사용합니다.
속성
- Promise.length
값이 언제나 1인 길이 속성입니다. (생성자 인수의 수) - Promise.prototype
Promise 생성자의 프로토타입을 나타냅니다.
메서드
-
- iterable 내의 모든 프로미스가 이행한 뒤 이행하고, 어떤 프로미스가 거부하면 즉시 거부하는 프로미스를 반환합니다.
반환된 프로미스가 이행하는 경우 iterable 내의 프로미스가 결정한 값을 모은 배열이 이행 값입니다.
반환된 프로미스가 거부하는 경우 iterable 내의 거부한 프로미스의 이유를 그대로 사용합니다.
이 메서드는 여러 프로미스의 결과를 모을 때 유용합니다. - Promise.all() 메서드는 순회 가능한 객체에 주어진 모든 프로미스가 이행한 후,
혹은 프로미스가 주어지지 않았을 때 이행하는 Promise를 반환합니다.
주어진 프로미스 중 하나가 거부하는 경우, 첫 번째로 거절한 프로미스의 이유를 사용해 자신도 거부합니다.
const promise1 = Promise.resolve(3); const promise2 = 42; const promise3 = new Promise((resolve, reject) => { setTimeout(resolve, 100, 'foo'); }); Promise.all(\[promise1, promise2, promise3\]).then((values) => { console.log(values); }); // expected output: Array \[3, 42, "foo"\]
- iterable 내의 모든 프로미스가 이행한 뒤 이행하고, 어떤 프로미스가 거부하면 즉시 거부하는 프로미스를 반환합니다.
-
Promise.allSettled(iterable)
메소드는 배열이나 별도의 나열 가능한 객체를 통해 나열된 Promise모음이 모두 이행하거나
거부했을 때에 대한 대응을 할 수 있는 Promise 객체를 반환한다.const promise1 = Promise.resolve(3); const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo')); const promises = \[promise1, promise2\]; Promise.allSettled(promises). then((results) => results.forEach((result) => console.log(result.status))); // expected output: // "fulfilled" // "rejected"
-
Promise.any(iterable)
Promise.any ()는 Promise 객체의 이터 러블을 취하고,
이터러블의 약속 중 하나가 충족되는 즉시 해당 약속의 값으로 해결되는 단일 약속을 반환합니다.
반복 가능한 이행에 약속이없는 경우 (주어진 모든 약속이 거부 된 경우) 반환 된 약속은
개별 오류를 그룹화하는 오류의 새 하위 클래스 인AggregateErro
r와 함께 거부됩니다.
기본적으로이 메서드는 Promise.all ()과 반대입니다.const promise1 = Promise.reject(0); const promise2 = new Promise((resolve) => setTimeout(resolve, 100, 'quick')); const promise3 = new Promise((resolve) => setTimeout(resolve, 500, 'slow')); const promises = [promise1, promise2, promise3]; Promise.any(promises).then((value) => console.log(value)); // expected output: "quick"
-
-
iterable
내의 어떤 프로미스가 이행하거나 거부하는 즉시 스스로 이행하거나 거부하는 프로미스를 반환합니다. -
이행 값이나 거부 이유는 원 프로미스의 값이나 이유를 그대로 사용합니다.
-
이 프로미스 객체는
iterable
안에 있는 프로미스 중에 가장 먼저 완료된 것의 결과값으로 그대로 이행하거나 거부합니다.const promise1 = new Promise((resolve, reject) => { setTimeout(resolve, 500, 'one'); }); const promise2 = new Promise((resolve, reject) => { setTimeout(resolve, 100, 'two'); }); Promise.race(\[promise1, promise2\]).then((value) => { console.log(value); // Both resolve, but promise2 is faster }); // expected output: "two"
-
race
함수는 인자로 주어진iterable
의 프로미스 중 가장 먼저 완료(settle)되는 것과 같은 방식으로 완료(이행/거부)되고, 같은 결과값을 전달하는 Promise를 반환합니다. -
전달받은
iterable
이 비어 있을 경우, 반환한 프로미스는 영원히 대기 상태가 됩니다. -
Iterable
에 프로미스가 아닌 값이나 이미 완료된 프로미스가 포함되어 있을 경우,Promise.race
는 전달받은iterable
에서 처음으로 등장하는 이러한 값을 결과값으로 이행합니다.
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이 더 빠르므로 거부함 });
-
-
Promise.reject()
Promise.reject(reason)
메서드는 주어진 이유(reason
)로 거부된Promise
객체를 반환합니다.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 });
-
-
주어진 값으로 이행하는 Promise 객체를 반환합니다.
-
값이 then 가능한 (즉, then 메서드가 있는) 경우, 반환된 프로미스는 then 메서드를 따라가고 마지막 상태를 취합니다.
-
그렇지 않은 경우 반환된 프로미스는 주어진 값으로 이행합니다.
-
어떤 값이 프로미스인지 아닌지 알 수 없는 경우, Promise.resolve(value) 후 반환값을 프로미스로 처리할 수 있습니다.
-
Promise.resolve(value)
메서드는 주어진 값으로 이행하는Promise.then
객체를 반환합니다. -
그 값이 프로미스인 경우, 해당 프로미스가 반환됩니다.
-
그 값이
thenable
(예, "then" 메소드 가 있음)인 경우, 반환된 프로미스는 그thenable
을 "따르며", 그 최종 상태를 취합니다. -
그렇지 않으면 반환된 프로미스는 그 값으로 이행합니다.
-
이 함수는 프로미스형의 객체(무언가를 결정하는 프로미스를 결정하는 프로미스 등)의 중첩된 레이어를 단일 레이어로 펼칩니다.
주의: 스스로를 결정하는 thenable 에서 Promise.resolve 를 호출하면 안됩니다.
이는 무한히 중첩된 프로미스를 펼치려고하므로 무한 재귀를 유발할 것입니다.Angular
에서async Pipe
를 함께 사용한 예제입니다. 자세한 내용은 여기에서 확인하세요.
const promise1 = Promise.resolve(123); promise1.then((value) => { console.log(value); // expected output: 123 });
-
value
: 이Promise
에 의해 결정되는 인수.Promise
또는 이행할thenable
일수도 있습니다. -
return: 주어진 값으로 이행된
Promise
또는 값이promise
객체인 경우, 값으로 전달된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 이 동작하는 방식에 대해 확인하세요.
-
-
Promise.catch(onRejected)
catch() 메서드는 Promise를 반환하고 거부 된 사례 만 처리합니다.
Promise.prototype.then(undefined, onRejected)를 호출하는 것과 동일하게 작동합니다.
(사실 obj.catch(onRejected)를 호출하면 내부적으로 obj.then(undefined, onRejected)를 호출합니다).
즉, 정의되지 않은 결과 값으로 폴백하려는 경우에도 onRejected 함수를 제공해야합니다 (예 :obj.catch(() => {})
).const promise1 = new Promise((resolve, reject) => { throw 'Uh-oh!'; }); promise1.catch((error) => { console.error(error); }); // expected output: Uh-oh!
-
-
finally()
메소드는 Promise 객체를 반환합니다.Promise
가 처리되면 충족되거나 거부되는지 여부에 관계없이 지정된 콜백 함수가 실행됩니다.
이것은Promise
가 성공적으로 수행 되었는지 거절되었는지에 관계없이Promise
가 처리 된 후에
코드가 무조건 한 번은 실행되는 것을 제공합니다.이것은 Promise의
then()
과catch()
핸들러에서의 코드 중복을 피하게 합니다. -
finally
핸들러는onFinally
라는 지정된 함수의Promise
가 반환됩니다. -
finally()
메서드는 결과에 관계없이 promise가 처리되면 무언가를 프로세싱 또는 정리를 수행하려는 경우에 유용합니다. -
finally()
메서드는.then(onFinally, onFinally)
를 호출하는 것과 매우 비슷하지만 몇 가지 차이점이 있습니다: -
함수를 인라인으로 만들 때, 두 번 선언해야 하지 않고 한 번만 전달하거나 그것을 위한 변수를 만들 수 있습니다.
-
finally
콜백은 어떠한 인수도 전달받지 않습니다,
왜냐하면promise
가 이행되었는지 또는 거부되었는지를 판단할 수 없기 때문입니다.promise
의 왜 거부되었는지 또는 이행되었을때 반환되는 값이 필요하지 않거나 제공할 필요가 없을 때 활용합니다. -
Promise.reject(3).finally(() => {})
(약속 안 함) )는 3으로 거부됩니다. -
Promise.resolve(2).then(() => {}, () => {})
(undefined
로 해결될) 와 달리,Promise.resolve(2).finally(() => {})
는 값 2로 해결됩니다. -
유사하게
Promise.reject(3).then(() => {}, () => {})
(undefined
로 거부될)와는 달리Promise.reject(3).finally(() => {})
는 값 3로 거부됩니다.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; });
-
Promise.then(onFulfilled, onRejected)
then()
메서드는Promise
를 리턴하고 두 개의 콜백 함수를 인수로 받습니다.
하나는Promise
가 이행했을 때, 다른 하나는 거부했을 때를 위한 콜백 함수입니다.매개변수 중 하나 이상을 생략했거나 함수가 아닌 값을 전달한 경우,
then
은 핸들러가 없는 것이 되지만 오류를 발생하지는 않습니다.then
바로 이전의Promise
가then
에 핸들러가 없는 상태로 완료(이행이나 거부)했을 경우, 추가 핸들러가 없는Promise
가 생성되며, 원래Promise
의 마지막 상태를 그대로 물려받습니다.-
onFulfilled
Promise
가 수행될 때 호출되는Function
으로, 이행 값(fulfillment value) 하나를 인수로 받습니다. -
onRejected
Promise
가 거부될 때 호출되는Function
으로, 거부 이유(rejection reason) 하나를 인수로 받습니다. -
Promise
가 이행하거나 거부했을 때, 각각에 해당하는 핸들러 함수(onFulfilled
나onRejected
)가 비동기적으로 실행됩니다.
핸들러 함수는 다음 규칙을 따라 실행됩니다.- 함수가 값을 반환할 경우, then에서 반환한 프로미스는 그 반환값을 자신의 결과값으로 하여 이행합니다.
- 값을 반환하지 않을 경우, then에서 반환한 프로미스는 undefined를 결과값으로 하여 이행합니다.
- 오류가 발생할 경우, then에서 반환한 프로미스는 그 오류를 자신의 결과값으로 하여 거부합니다.
- 이미 이행한 프로미스를 반환할 경우, then에서 반환한 프로미스는 그 프로미스의 결과값을 자신의 결과값으로 하여 이행합니다.
- 이미 거부한 프로미스를 반환할 경우, then에서 반환한 프로미스는 그 프로미스의 결과값을 자신의 결과값으로 하여 거부합니다.
- 대기 중인 프로미스를 반환할 경우, then에서 반환한 프로미스는 그 프로미스의 이행 여부와 결과값을 따릅니다.
- 다음 예제에서 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
과Promise.prototype.catch()
메서드는 프로미스를 반환하기 때문에, 체이닝이 가능합니다.
이를 composition(구성) 이라고도 합니다.
-