Promise 개체는 비동기 작업의 최종 완료(또는 실패)와 결과 값을 나타냅니다.

여기서는 Promise 생성자를 다룹니다. 프로미스에 대해 알아보려면 Using promises 를 먼저 읽어보세요. 생성자는 주로 프로미스를 지원하지 않는 함수를 감싸는데 사용됩니다.

구문

new Promise( /* executor */ function(resolve, reject) { ... } );

매개변수

executor
resolvereject 인수와 함께 전달되는 함수입니다. executor 함수는 Promise 구현에 의해 즉시 실행되고 resolvereject 함수를 전달합니다 (Executor는 Promise 생성자가 생성 된 객체를 반환하기 전에 호출됩니다). resolve 및 reject 기능은 호출 될 때 마다 promise를 해결(resolve)하거나 거부(reject)합니다. Executor는 보통 몇몇 비동기(asynchronous) 작업을 시작한 다음 이것이 완료되었을 때 resolve 함수를 호출하여 promise를 해결하거나 오류가 발생하면 거부(reject)합니다.
executor 함수에서 오류가 발생하면 promise는 거부(rejected)됩니다. executor의 반환값은 무시됩니다.

설명

Promise는 프로미스가 생성될 때 꼭 알 필요는 없는 값을 위한 대리자입니다. 이는 비동기 동작이 종료된 이후의 결과값이나 실패 이유를 처리하기 위한 처리기(handler)를 연결할 수 있도록 합니다. 프로미스는 비동기 메서드가 동기 메서드처럼 값을 반환하도록 합니다. 최종값 대신, 비동기 메서드는 미래 어느 시점에 값을 갖는 promise를 반환합니다.

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

  • 대기(pending): 이행되거나 거부되지 않은 초기 상태.
  • 이행(fulfilled): 연산이 성공적으로 완료됨.
  • 거부(rejected): 연산이 실패함.

대기중인 프로미스는 값과 함께 이행되거나, 어떤 이유(오류)로 인해 거부될 수 있습니다. 이 중 하나가 일어난 경우, 연결된 핸들러는 호출된 프로미스의 then 메서드에 의해 대기열에 오릅니다(queued up). (핸들러가 붙는 시점에 프로미스가 이미 이행 또는 거부됐더라도 핸들러를 호출합니다. 따라서 비동기 연산과 부착하는 핸들러 사이에는 경합 조건(race condition)이 없습니다.)

Promise.prototype.then()Promise.prototype.catch() 메서드가 프로미스를 반환하기에, 둘은 연결(chain)될 수 있습니다

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

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

속성

Promise.length
값이 언제나 1인 Length 속성입니다. (생성자 인수의 수를 나타냅니다.)
Promise.prototype
Promise 생성자의 프로토타입을 나타냅니다.

메서드

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

Promise 프로토타입

속성

Promise.prototype.constructor
인스턴스의 프로토타입을 만드는 함수를 반환합니다. 이는 기본으로 Promise 함수입니다.

메서드

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

Promise 생성하기

Promise 오브젝트는 new 키워드와 생성자를 사용하여 만듭니다. 이 생성자는 인수로 "executor 함수"라는 함수를 사용합니다. 이 함수는 매개 변수로 두 가지 함수를 가져야 합니다. 비동기 작업이 성공적으로 완료되고 결과를 값으로 반환하면 첫 번째 함수(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);
});

고급 예제

이 간단한 예는 Promise의 메커니즘을 보여줍니다. testPromise() 메서드는 <button>이 클릭될 때마다 호출됩니다. window.setTimeout()을 사용하여 1-3 초마다 promise count (1부터 시작하는 숫자)까지 무작위로 promise를 만듭니다., Promise() 생성자는 프로미스를 만드는 데 쓰입니다.

프로미스 fulfillment는 p1.then()을 사용하는 fulfill callbqck 세트를 통해 간단하게 기록(log)됩니다. 약간의 로그는 메서드의 동기 부분이 promise의 비동기 완료(completion)와 분리(decouple)되는 것을 보여줍니다.

'use strict';
var promiseCount = 0;

function testPromise() {
    var thisPromiseCount = ++promiseCount;

    var log = document.getElementById('log');
    log.insertAdjacentHTML('beforeend', thisPromiseCount +
        ') Started (<small>Sync code started</small>)<br/>');

    // 새 약속을 (생성)합니다: 이 프로미스의 숫자 셈을 약속합니다, 1부터 시작하는(3s 기다린 뒤)
    var p1 = new Promise(
        // resolver(결정자) 함수는 프로미스 (이행을) 결정 또는 거부하는
        // 능력과 함께 호출됩니다
        function(resolve, reject) {
            log.insertAdjacentHTML('beforeend', thisPromiseCount +
                ') Promise started (<small>Async code started</small>)<br/>');
            // 이는 비동기를 만드는 예에 불과합니다
            window.setTimeout(
                function() {
                    // 프로미스 이행 !
                    resolve(thisPromiseCount);
                }, Math.random() * 2000 + 1000);
        }
    );

    // 프로미스가 then() 호출로 결정된/이행된 경우 무엇을 할 지를 정의하고,
    // catch() 메서드는 프로미스가 거부된 경우 무엇을 할 지를 정의합니다.
    p1.then(
        // 이행값 기록
        function(val) {
            log.insertAdjacentHTML('beforeend', val +
                ') Promise fulfilled (<small>Async code terminated</small>)<br/>');
        })
    .catch(
        // 거부 이유 기록
        function(reason) {
            console.log('Handle rejected promise ('+reason+') here.');
        });

    log.insertAdjacentHTML('beforeend', thisPromiseCount +
        ') Promise made (<small>Sync code terminated</small>)<br/>');
}

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

XHR로 이미지 로딩

이미지를 로드하기 위해 PromiseXMLHttpRequest를 사용하는 또 다른 간단한 예는 MDN GitHub js-examples 저장소에서 이용할 수 있습니다. 실제 예를 볼 수도 있습니다. 각 단계는 주석이 있어 프로미스 및 XHR 구조를 철저히 따르도록 해줍니다.

Specifications

스펙 상태 설명
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Promise' in that specification.
Standard ECMA 표준에서 초기 정의.
ECMAScript Latest Draft (ECMA-262)
The definition of 'Promise' in that specification.
Draft  

브라우저 호환성

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidEdge MobileFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
Basic supportChrome Full support 32Edge Full support YesFirefox Full support 29IE No support NoOpera Full support 19Safari Full support 8WebView Android Full support 4.4.3Chrome Android Full support 32Edge Mobile Full support YesFirefox Android Full support 29Opera Android Full support YesSafari iOS Full support 8Samsung Internet Android Full support Yesnodejs Full support 0.12
Promise() constructorChrome Full support 32Edge Full support YesFirefox Full support 29
Notes
Full support 29
Notes
Notes Constructor requires a new operator since version 37.
IE No support NoOpera Full support 19Safari Full support 8
Notes
Full support 8
Notes
Notes Constructor requires a new operator since version 10.
WebView Android Full support 4.4.3Chrome Android Full support 32Edge Mobile Full support YesFirefox Android Full support 29
Notes
Full support 29
Notes
Notes Constructor requires a new operator since version 37.
Opera Android Full support YesSafari iOS Full support 8
Notes
Full support 8
Notes
Notes Constructor requires a new operator since version 10.
Samsung Internet Android Full support Yesnodejs Full support 0.12
Notes
Full support 0.12
Notes
Notes Constructor requires a new operator since version 4.
allChrome Full support 32Edge Full support YesFirefox Full support 29IE No support NoOpera Full support 19Safari Full support 8WebView Android Full support 4.4.3Chrome Android Full support 32Edge Mobile Full support YesFirefox Android Full support 29Opera Android Full support YesSafari iOS Full support 8Samsung Internet Android Full support Yesnodejs Full support 0.12
prototypeChrome Full support 32Edge Full support YesFirefox Full support 29IE No support NoOpera Full support 19Safari Full support 8WebView Android Full support 4.4.3Chrome Android Full support 32Edge Mobile Full support YesFirefox Android Full support 29Opera Android Full support YesSafari iOS Full support 8Samsung Internet Android Full support Yesnodejs Full support 0.12
catchChrome Full support 32Edge Full support YesFirefox Full support 29IE No support NoOpera Full support 19Safari Full support 8WebView Android Full support 4.4.3Chrome Android Full support 32Edge Mobile Full support YesFirefox Android Full support 29Opera Android Full support YesSafari iOS Full support 8Samsung Internet Android Full support Yesnodejs Full support 0.12
finallyChrome Full support 63Edge Full support 18Firefox Full support 58IE No support NoOpera Full support 50Safari Full support 11.1WebView Android Full support 63Chrome Android Full support 63Edge Mobile No support NoFirefox Android Full support 58Opera Android Full support 50Safari iOS Full support 11.1Samsung Internet Android No support Nonodejs Full support 10.0.0
thenChrome Full support 32Edge Full support YesFirefox Full support 29IE No support NoOpera Full support 19Safari Full support 8WebView Android Full support 4.4.3Chrome Android Full support 32Edge Mobile Full support YesFirefox Android Full support 29Opera Android Full support YesSafari iOS Full support 8Samsung Internet Android Full support Yesnodejs Full support 0.12
raceChrome Full support 32Edge Full support YesFirefox Full support 29IE No support NoOpera Full support 19Safari Full support 8WebView Android Full support 4.4.3Chrome Android Full support 32Edge Mobile Full support YesFirefox Android Full support 29Opera Android Full support YesSafari iOS Full support 8Samsung Internet Android Full support Yesnodejs Full support 0.12
rejectChrome Full support 32Edge Full support YesFirefox Full support 29IE No support NoOpera Full support 19Safari Full support 8WebView Android Full support 4.4.3Chrome Android Full support 32Edge Mobile Full support YesFirefox Android Full support 29Opera Android Full support YesSafari iOS Full support 8Samsung Internet Android Full support Yesnodejs Full support 0.12
resolveChrome Full support 32Edge Full support YesFirefox Full support 29IE No support NoOpera Full support 19Safari Full support 8WebView Android Full support 4.4.3Chrome Android Full support 32Edge Mobile Full support YesFirefox Android Full support 29Opera Android Full support YesSafari iOS Full support 8Samsung Internet Android Full support Yesnodejs Full support 0.12

Legend

Full support  
Full support
No support  
No support
See implementation notes.
See implementation notes.

참조

문서 태그 및 공헌자

최종 변경자: urty5656,