상세 컨텐츠

본문 제목

JavaScript - Promise

카테고리 없음

by Yongari 2023. 1. 24. 19:59

본문

 

Promise는 무엇인가??

 

 

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

 

 

Promise를 사용하는 이유:

 

 

비동기 메서드에서 마치 동기메서드처럼 값을 반환할 수 있고 최종결과를 반환하는 것이 아닌 미래의 어떤 시점에 결과를 제공하겠다는 약속을 반환함

 

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

 

대기(pending) : 이행하지도, 거부하지도 않은 초기 상태

이행(fulfilled) : 연산이 성공적으로 완료됨

거부(rejected) : 연산이 실패함

 

대기중인 프로미스는 값과 함께 이행할 수도 어떤 이유로 인해 거부될 수도 있습니다. 이행이나 거부될 때 프로미스의 then 메서드에 의해 대기열(큐)에 추가된 처리기들이 호출된다. 

 

 

 

 

mdn 링크 참고 

 

Promise - JavaScript | MDN

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

developer.mozilla.org



생성자

Promise() : 새로운 Promise 객체를 생성합니다. 주로 프로미스를 지원하지 않는 함수를 감쌀 때 사용함

 

정적 메서드

Promise.all(iterable) : 주어진 프로미스가 이행하거나 한 프로미스가 거부될떄까지 대기하는 새로운 프로미스를 반환

Promise.allSettled(iterable) : 주어진 모든 프로미스가 처리(이행 또는 거부)될떄까지 대기하는 새로운 프로미스를 반환

Promise.any(iterable) : 주어진 프로미스 중 하나라도 실행되면 즉시 그 프로미스값으로 이행하는 새로운 프로미스를 반환

Promise.race(iterable) : 주어진 프로미스 중 하나라도 처리할 때까지 대기하는 프로미스를 반환

Promise.reject(reason) : 주어진 사유로 거부하는 Promise 객체를 반환

Promise.resolve() : 주어진 값으로 이행하는 Promise 객체를 반환

 

예제 코드 실행 

 

let myFirstPromise = new Promise((resolve, reject) => {
  // 우리가 수행한 비동기 작업이 성공한 경우 resolve(...)를 호출하고, 실패한 경우 reject(...)를 호출합니다.
  // 이 예제에서는 setTimeout()을 사용해 비동기 코드를 흉내냅니다.
  // 실제로는 여기서 XHR이나 HTML5 API를 사용할 것입니다.
  setTimeout( function() {
    resolve("성공!")  // 와! 문제 없음!
  }, 250)
})

myFirstPromise.then((successMessage) => {
  // successMessage는 위에서 resolve(...) 호출에 제공한 값입니다.
  // 문자열이어야 하는 법은 없지만, 위에서 문자열을 줬으니 아마 문자열일 것입니다.
  console.log("와! " + successMessage)
});

 

예제 코드 결과값

 

와! 성공!

 

다음은 Promise의 동작방식을 보여주고 있습니다.
1. testPromise()함수는 버튼 클릭시마다 호출
2. window.setTimeout()을 사용해 1~3초 무작위 간격이후 프로미스 횟수로 이행하는 프로미스 생성 

3. 프로미스 이행은 p1.then을 사용하는 이행 콜백 세트를 통해 로그에 남음

 

다음 두가지 코드를 파일로 만들어서 테스트할 수 있습니다.

 

test.html

<button id="btn">프로미스 만들기!</button>
<div id="log"></div>

 

test.js 

'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.";
}

 

 

참고링크 : mdn