프로미스가 어떻게 동작하는지 이해하기위해 먼저 함수패턴으로 구현한 비동기와 promise로 구현한 코드를 비교해서 살펴보자
비동기 통신 함수형식
function getData(callbackFunc) {
$.get('url 주소/products/1', function(response) {
callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
});
}
getData(function(tableData) {
console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
});
promise로 변환한 비동기통신
function getData(callback) {
// new Promise() 추가
return new Promise(function(resolve, reject) {
$.get('url 주소/products/1', function(response) {
// 데이터를 받으면 resolve() 호출
resolve(response);
});
});
}
// getData()의 실행이 끝나면 호출되는 then()
getData().then(function(tableData) {
// resolve()의 결과 값이 여기로 전달됨
console.log(tableData); // $.get()의 reponse 값이 tableData에 전달됨
});
콜백함수로 처리하던 구조에서 new Promise(), resoleve(), then()과 같은 새로워보이는 프로미스 API 구조로 바뀌었다.
Pending(대기)
new Promise(function(resolve, reject) {
// ...
});
new Promise()와 같이 메서드를 호출하면 대기상태가 된다. 콜백함수를 선언할수 있고 콜백함수의 인자는 resolve와 reject다.
Fulfilled(이행)
new Promise(function(resolve, reject) {
resolve();
});
여기서 인자 resolve를 실행하면 이행상태가 된다. 이행상태가 되면 아래와같이 then()을 이용하여 처리 결과 값을 받을 수 있게 된다.
function getData() {
return new Promise(function(resolve, reject) {
var data = 100;
resolve(data);
});
}
// resolve()의 결과 값 data를 resolvedData로 받음
getData().then(function(resolvedData) {
console.log(resolvedData); // 100
});
Rejected(실패)
function getData() {
return new Promise(function(resolve, reject) {
reject(new Error("Request is failed"));
});
}
// reject()의 결과 값 Error를 err에 받음
getData().then().catch(function(err) {
console.log(err); // Error: Request is failed
});
실패 상태가되면 실패한 이유(실패처리의 결과값)를 catch()로 받을수 있다.
function getData() {
return new Promise(function(resolve, reject) {
$.get('url 주소/products/1', function(response) {
if (response) {
resolve(response);
}
reject(new Error("Request is failed"));
});
});
}
// 위 $.get() 호출 결과에 따라 'response' 또는 'Error' 출력
getData().then(function(data) {
console.log(data); // response 값 출력
}).catch(function(err) {
console.error(err); // Error 출력
});
위 코드는 서버에서 제대로 응답을 받아오면 resolve() 메서드를 호출하고, 응답이 없으면 reject() 메서드를 호출하는 예제이다. 호출된 메서드에 따라 then()이나 catch()로 분기하여 응답 결과 또는 오류를 한다.
또다른 then 예제
new Promise(function(resolve, reject){
setTimeout(function() {
resolve(1);
}, 2000);
})
.then(function(result) {
console.log(result); // 1
return result + 10;
})
.then(function(result) {
console.log(result); // 11
return result + 20;
})
.then(function(result) {
console.log(result); // 31
});
promise 에러처리
function getData() {
return new Promise(function(resolve, reject) {
reject('failed');
});
}
// 1. then()의 두 번째 인자로 에러를 처리하는 코드
getData().then(function() {
// ...
}, function(err) {
console.log(err);
});
// 2. catch()로 에러를 처리하는 코드
getData().then().catch(function(err) {
console.log(err);
});
에러처리는 두가지 방법이 있는데 첫번째는 두번째 인자로 에러를 처리하는것이고, 두번째는 catch함수로 에러를 처리하는것이다.
두가지 방법이 있지만 인자로 처리했을시 오류를 제대로 잡아내지 못하는 경우가 생기기 때문에 더 많은 예외 처리 상황을 위해 프로미스의 끝에 가급적 catch()를 붙이길 추천한다.
출처 : https://joshua1988.github.io/web-development/javascript/promise-for-beginners/