PROMISE

앞선 글의 콜백 지옥 을 해결하기 위한 방법 중 하나로 Promise 패턴이 제안되었다.

jQuery에서는 완전하진 않지만 Promise패턴이 Deferred 로 사용되고 있다.

Promise 패턴을 사용하면 1. 비동기 작업들을 순차적으로 진행하고나, 병렬로 진행하는 등의 제어가 수월해지고 2. 코드의 가독성이 좋아진다. 또한 내부적으로 예외처리에 대한 구조가 탄탄해, 오류 발생 시 3. 오류 처리에 대해 보다 직관적으로 관리해줄 수 있는 장점이 있다.

Promise는 비동기 처리가 성공(fulfilled)했는지, 실패(rejected)했는지 등의 상태 정보와 처리 종료후 실행될 콜백함수(then, catch)를 담고 있는 객체이다.

Promise는 주로 서버에서 받아온 데이터를 화면에 표시할 때 사용하며, 일반적으로 웹 애플리케이션을 구현할 때 서버에서 데이터를 요청하고 받아오기 위해 다음과 같이 사용한다.

var _promise = function(param){
    return new Promise(function (){
        // setTimeout함수로 비동기 
        window.setTimeout(function(){
            if(param){
                resolve("해결완료");
            }else{
              	reject(Error("실패"));  
            }
        },30000);
    });
};

//promise 실행
_promise(true).then(function(text){
    console.log(text);
},function(error){
    console.error(error);
});

//=> "해결 완료"

위의 코드는 Promise 선언과 실행 두 부분으로 나눌 수 있다.

Promise의 states

Promise는 사전적 의미로 "약속"이다. js에서는 "지금은 없는데 이상없으면 이따가 주고 없으면 알려줄게"라는 약속으로 볼 수 있다. 따라서 promise는 다음과 같은 상태(state)를 가진다.

  1. pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태. (약속을 수행 중인 상태)

  2. fulfilled(이행) : 비동기 처리가 완료되어 promise가 결과 값을 반환해준 상태. (약속이 지켜진 상태)

  3. rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태(약속이 못 지켜진 상태)

  4. settled : 비동기 처리가 실패이든 성공이든 결론이 난 상태이다.

각 상태를 차례대로 살펴보자.

Pending

다음과 같이 new Promise() 메서드를 호출하면 pending 상태가 된다.

메서드를 호출할 때 콜백 함수의 인자로 resolve, reject 에 접근 할 수 있다.

promsie가 생성된 직후부터 resolve나 reject가 호출되기 전까지의 상태이다.

Fulfilled

콜백 함수의 인자인 resolve를 다음과 같이 실행하면 fulfilled(이행) 상태가 된다. fulfilled상태가 되면 아래와 같이 then() 을 이용해 처리 결과 값을 받을 수 있다.

Rejected

콜백 함수 인자인 reject로 reject() 메서드를 실행하면 rejected(실패) 상태가된다. rejected 상태가 되면 실패한 이유(실패 처리의 결과 값)를 아래와 같이 catch() 로 받을 수 있다.

오류가 발생했을 때 catch() 말고 then()만을 사용하여 처리할 수도 있다.

두 가지 방법을 사용해서 오류를 처리할 수 있지만 가급적이면 catch 를 사용하는 것이 좋다. 왜냐하면 then()의 두번째 인자로는 다음 예시와 같이 오류를 감지 못하는 경우가 있기 때문이다.

더 많은 예외 처리 상황을 위해서는 catch()를 사용하는 것이 좋다.

예제

위의 코드는 서버에서 응답을 제대로 받아오면 resolve() 메서드 호출, 응답이 없으면 reject() 메서드를 호출하는 예제이다. 호출된 메서드에 따라 then()이나 catch()로 분기하여 결과값을 출력한다.

Promise Chaining

여러개의 Promise 여러개를 연결하여 사용할 수 있다.

다음과 같이 then() 메서드를 호출하여 여러개를 연결 할 수 있다.

예시

실무에서 있을 법한 예시는 다음과 같다.

예를 들어, 사용자 정보를 받아와 파싱, 인증 등의 작업을 거치는 코드를 살펴볼 것이다.

다음과 같이 여러개의 프로미스를 .then() 으로 연결하여 처리할 수 있다.

Promise.all

여러개의 비동기 작업들이 존재하고 그 작업들이 모두 완료되었을 때 다음 작업을 진행하고 싶은 경우에 활용하면된다.

참조페이지

Last updated

Was this helpful?