Promise 개체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타냅니다.
참고: 여기서는 Promise 생성자와, 인스턴스의 메서드 및 속성을 다룹니다. 프로미스의 동작 방식이나 실제 사용법은 프로미스 사용하기에서 확인할 수 있습니다. 생성자는 주로 프로미스를 지원하지 않는 함수를 감쌀 때 사용합니다.
The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.
구문
new Promise(executor);
매개변수
executorresolve및reject인수를 전달할 실행 함수. 실행 함수는 프로미스 구현에 의해resolve와reject함수를 받아 즉시 실행됩니다(실행 함수는Promise생성자가 생성한 객체를 반환하기도 전에 호출됩니다).resolve및reject함수는 호출할 때 각각 프로미스를 이행하거나 거부합니다. 실행 함수는 보통 어떤 비동기 작업을 시작한 후 모든 작업을 끝내면resolve를 호출해 프로미스를 이행하고, 오류가 발생한 경우reject를 호출해 거부합니다. 실행 함수에서 오류를 던지면 프로미스는 거부됩니다. 실행 함수의 반환값은 무시됩니다.
설명
Promise는 프로미스가 생성될 때 꼭 알 수 있지는 않은 값을 위한 대리자로, 비동기 연산이 종료된 이후의 결과값이나 실패 이유를 처리하기 위한 처리기를 연결할 수 있도록 합니다. 프로미스를 사용하면 비동기 메서드에서 마치 동기 메서드처럼 값을 반환할 수 있습니다. 다만 최종 결과를 반환하지는 않고, 대신 프로미스를 반환해서 미래의 어떤 시점에 결과를 제공합니다.
Promise는 다음 중 하나의 상태를 가집니다.
- 대기(pending): 이행하거나 거부되지 않은 초기 상태.
- 이행(fulfilled): 연산이 성공적으로 완료됨.
- 거부(rejected): 연산이 실패함.
대기 중인 프로미스는 값과 함께 이행할 수도, 어떤 이유(오류)로 인해 거부될 수 있습니다. 이행이나 거부될 때, 프로미스에 연결한 처리기는 그 프로미스의 then 메서드에 의해 대기열에 오릅니다. 이미 이행했거나 거부된 프로미스에 연결한 처리기도 호출하므로, 비동기 연산과 처리기 연결 사이에 경합 조건race condition은 없습니다.
Promise.prototype.then() 및 Promise.prototype.catch() 메서드의 반환 값은 다른 프로미스이므로, 서로 연결할 수 있습니다.

혼동 주의: 느긋한 계산법 및 연산 연기를 위한 방법을 프로미스라고 부르는 다른 언어(예: Scheme)가 여럿 있습니다. 반면 JavaScript에서 프로미스는 콜백 함수를 연결할 수 있는 이미 진행 중인 프로세스를 나타냅니다. 표현식을 느긋하게 평가하려면 인수 없는 화살표 함수 f = () => expression를 사용하고, f()를 사용해 평가하세요.
참고: 프로미스는 대기 중이지 않으며 이행 또는 거부됐을 때 처리(settled)됐다고 말합니다. 프로미스와 함께 쓰이는 단어 resolved는 프로미스가 다른 프로미스의 상태에 맞춰 처리됨, 또는 상태가 "잠김"되었다는 의미입니다. 용어에 관한 더 자세한 설명은 Domenic Denicola의 글 States and fates에서 볼 수 있습니다.
속성
Promise.length- 값이 언제나 1인 길이 속성입니다. (생성자 인수의 수)
Promise.prototypePromise생성자의 프로토타입을 나타냅니다.
메서드
Promise.all(iterable)iterable내의 모든 프로미스가 이행한 뒤 이행하고, 어떤 프로미스가 거부하면 즉시 거부하는 프로미스를 반환합니다. 반환된 프로미스가 이행하는 경우iterable내의 프로미스가 결정한 값을 모은 배열이 이행 값입니다. 반환된 프로미스가 거부하는 경우iterable내의 거부한 프로미스의 이유를 그대로 사용합니다. 이 메서드는 여러 프로미스의 결과를 모을 때 유용합니다.Promise.race(iterable)iterable내의 어떤 프로미스가 이행하거나 거부하는 즉시 스스로 이행하거나 거부하는 프로미스를 반환합니다. 이행 값이나 거부 이유는 원 프로미스의 값이나 이유를 그대로 사용합니다.
Promise.reject()- 주어진 이유로 거부하는
Promise객체를 반환합니다.
Promise.resolve()- 주어진 값으로 이행하는
Promise객체를 반환합니다. 값이then가능한 (즉,then메서드가 있는) 경우, 반환된 프로미스는then메서드를 따라가고 마지막 상태를 취합니다. 그렇지 않은 경우 반환된 프로미스는 주어진 값으로 이행합니다. 어떤 값이 프로미스인지 아닌지 알 수 없는 경우,Promise.resolve(value)후 반환값을 프로미스로 처리할 수 있습니다.
Promise 프로토타입
속성
Promise.prototype.constructor- 인스턴스의 프로토타입을 만드는 함수를 반환합니다. 기본값은
Promise함수입니다.
메서드
Promise.prototype.catch()- 프로미스(promise)에 거부 처리기 콜백을 추가하고 호출된 경우 콜백의 반환값 또는 프로미스가 대신 이행된 경우 그 원래 이행(fulfillment)값으로 결정하는(resolving) 새 프로미스를 반환합니다.
Promise.prototype.then()- 프로미스에 이행 또는 거부 처리기를 추가하고 호출된 처리기의 반환값 또는 프로미스가 처리되지 않은 경우 그 원래 처리된(settled) 값으로 결정하는 새 프로미스를 반환합니다 (즉 관련 처리기
onFulfilled또는onRejected가undefined인 경우). 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.
Promise 생성하기
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();
});
}
예제
기본 예제
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);
});
고급 예제
<button id="btn">프로미스 만들기!</button> <div id="log"></div>
다음의 작은 예제는 Promise의 동작 방식을 보여줍니다. testPromise() 함수는 <button>을 클릭할 때마다 호출되며, window.setTimeout()을 사용해 1~3초의 무작위 간격 이후 프로미스 횟수(1부터 시작하는 숫자)로 이행하는 프로미스를 생성합니다. Promise() 생성자는 프로미스를 만드는 데 쓰입니다.
프로미스 이행은 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/>');
}
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.";
}
이 예제는 버튼을 클릭하면 실행됩니다. Promise를 지원하는 브라우저가 필요합니다. 짧은 시간 안에 버튼을 여러 번 클릭하여, 서로 다른 프로미스가 번갈아 이행되는 것을 볼 수도 있습니다.
XHR로 이미지 불러오기
이미지를 로드하기 위해 Promise 및 XMLHttpRequest를 사용하는 또 다른 간단한 예는 MDN GitHub js-examples 저장소에서 이용할 수 있습니다. 실제 예를 볼 수도 있습니다. 각 단계에 주석이 붙어있어, 프로미스 및 XHR 구조를 차근차근 따라갈 수 있습니다.
명세
브라우저 호환성
| Desktop | Mobile | Server | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Promise | Chrome Full support 32 | Edge Full support Yes | Firefox Full support 29 | IE No support No | Opera Full support 19 | Safari Full support 8 | WebView Android Full support 4.4.3 | Chrome Android Full support 32 | Firefox Android Full support 29 | Opera Android Full support Yes | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support 0.12 |
Promise() constructor | Chrome Full support 32 | Edge Full support Yes | Firefox
Full support
29
| IE No support No | Opera Full support 19 | Safari
Full support
8
| WebView Android Full support 4.4.3 | Chrome Android Full support 32 | Firefox Android
Full support
29
| Opera Android Full support Yes | Safari iOS
Full support
8
| Samsung Internet Android Full support Yes | nodejs
Full support
0.12
|
all() | Chrome Full support 32 | Edge Full support 12 | Firefox Full support 29 | IE No support No | Opera Full support 19 | Safari Full support 8 | WebView Android Full support 4.4.3 | Chrome Android Full support 32 | Firefox Android Full support 29 | Opera Android Full support Yes | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support 0.12 |
allSettled() | Chrome Full support 76 | Edge No support No | Firefox No support No | IE No support No | Opera ? | Safari ? | WebView Android Full support 76 | Chrome Android Full support 76 | Firefox Android No support No | Opera Android Full support Yes | Safari iOS ? | Samsung Internet Android ? | nodejs Full support 12.9.0 |
catch() | Chrome Full support 32 | Edge Full support 12 | Firefox Full support 29 | IE No support No | Opera Full support 19 | Safari Full support 8 | WebView Android Full support 4.4.3 | Chrome Android Full support 32 | Firefox Android Full support 29 | Opera Android Full support Yes | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support 0.12 |
finally() | Chrome Full support 63 | Edge Full support 18 | Firefox Full support 58 | IE No support No | Opera Full support 50 | Safari Full support 11.1 | WebView Android Full support 63 | Chrome Android Full support 63 | Firefox Android Full support 58 | Opera Android Full support 46 | Safari iOS Full support 11.1 | Samsung Internet Android No support No | nodejs Full support 10.0.0 |
prototype | Chrome Full support 32 | Edge Full support Yes | Firefox Full support 29 | IE No support No | Opera Full support 19 | Safari Full support 8 | WebView Android Full support 4.4.3 | Chrome Android Full support 32 | Firefox Android Full support 29 | Opera Android Full support Yes | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support 0.12 |
race() | Chrome Full support 32 | Edge Full support 12 | Firefox Full support 29 | IE No support No | Opera Full support 19 | Safari Full support 8 | WebView Android Full support 4.4.3 | Chrome Android Full support 32 | Firefox Android Full support 29 | Opera Android Full support Yes | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support 0.12 |
reject() | Chrome Full support 32 | Edge Full support 12 | Firefox Full support 29 | IE No support No | Opera Full support 19 | Safari Full support 8 | WebView Android Full support 4.4.3 | Chrome Android Full support 32 | Firefox Android Full support 29 | Opera Android Full support Yes | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support 0.12 |
resolve() | Chrome Full support 32 | Edge Full support 12 | Firefox Full support 29 | IE No support No | Opera Full support 19 | Safari Full support 8 | WebView Android Full support 4.4.3 | Chrome Android Full support 32 | Firefox Android Full support 29 | Opera Android Full support Yes | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support 0.12 |
then() | Chrome Full support 32 | Edge Full support 12 | Firefox Full support 29 | IE No support No | Opera Full support 19 | Safari Full support 8 | WebView Android Full support 4.4.3 | Chrome Android Full support 32 | Firefox Android Full support 29 | Opera Android Full support Yes | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support 0.12 |
Legend
- Full support
- Full support
- No support
- No support
- Compatibility unknown
- Compatibility unknown
- See implementation notes.
- See implementation notes.
같이 보기
- 프로미스 사용하기
- Promises/A+ 스펙
- Venkatraman.R - JS Promise (Part 1, Basics)
- Venkatraman.R - JS Promise (Part 2 - Using Q.js, When.js and RSVP.js)
- Venkatraman.R - Tools for Promises Unit Testing
- Jake Archibald: JavaScript Promises: There and Back Again
- Domenic Denicola: Callbacks, Promises, and Coroutines – Asynchronous Programming Patterns in JavaScript
- Matt Greer: JavaScript Promises ... In Wicked Detail
- Forbes Lindesay: promisejs.org
- Promise polyfill
- Udacity: JavaScript Promises