저번 포스트에서 자바스크립트의 비동기 특성으로 인한 문제를 해결하기 위해 콜백 함수를 사용했었다. 그러나 콜백 함수는 콜백 지옥이라는 치명적인 단점이 있다. 이 단점을 해결하기 위해 ES6부터 새로 등장한 문법이 바로 Promise이다. 이름에서 알 수 있듯이, Promise는 미래에 실패하거나 성공한 결과값을 약속하는 것이다. 이는 어떤 작업의 성공과 실패를 분리하여 반환한다. 성공은 then으로, 실패는 catch로 값을 받게 된다. 아래의 예시 코드를 보자.
function promise1(flag){
return new Promise(
function(resolve, reject){
if(flag){
resolve(`프로미스 이행(fullfilled)! 성공!${flag}`)
}else {
reject(`프로미스 거절(rejected) 상태... 실패...${flag}`)
}
}
)
}
promise1(5 > 3)
.then(function(result){
console.log(result);
})
.catch(function(err){
console.log(err);
})
promise1(5 < 3)
.then((result) =>console.log(result))
.catch((err)=> console.log(err))
new 연산자를 이용해서 Promise 객체를 만들고 반환한다. 이 객체는 실행 함수를 포함하며, 이 실행 함수는 두 개의 콜백 함수인 resolve와 reject를 받는다. 위의 코드에서 flag가 true면 resolve 함수를 실행하고, false이면 reject 함수를 실행한다.
밑의 소비 코드에서 5 > 3은 true이므로 .then으로 값을 받게 된다. 반면 5 < 3은 false이므로 .catch로 값을 받는다.
.then과 .catch는 항상 콜백 함수를 인자로 받아야 한다.
이제, 저번 시간에 콜백 함수를 이용해 수정한 코드를 이번에는 Promise를 이용해서 다시 수정해 보자.
let product;
let price;
function goMart(){
console.log('마트에 가서 어떤 음료를 살지 고민한다');
}
function pickDrink(){
return new Promise(function(resolve, reject){
setTimeout(function(){
console.log('고민 끝');
product = '제로 콜라';
price = 6000;
if(price <= 3000){
resolve();
}
else {
reject();
}
},3000)
})
}
function pay (){
console.log(`상품명: ${product} // 가격: ${price}`)
}
function nopay(){
console.log(`금액 부족`);
}
goMart();
pickDrink().then(pay).catch(nopay);
//pickDrink가 성공한다면 pay라는 함수 실행해줘. 실패하면 nopay 실행
위의 코드를 보면, new로 Promise 객체를 만든 것을 볼 수 있다. 그리고 여기서 resolve와 reject 콜백 함수를 받아 price가 3000 이하이면 resolve 함수를 실행하고, 아니면 reject 함수를 실행한다. pickDrink 함수 다음에 pay 또는 noPay 함수가 실행되어야 하므로 .then과 .catch에 콜백 함수를 넣는다.