비동기적으로 실행하는 작업의 결과(성공/실패)를 나타내는 객체이다.
비동기 결과를 객체화 시킨다는 점이 Promise의 가장 큰 장점이자 특징이다!
Promise는 콜백을 예측 가능한 패턴으로 사용할 수 있게 해주며, Promise 없이 콜백만 사용했을 때 나타날 수 있는 엉뚱한 현상이나 찾기 힘든 버그를 상당 수 해결한다.
Promise 기반의 비동기적 함수를 호출하면, 해당 함수가 인스턴스를 반환한다.
Promise는 성공(fullfilled)하거나, 실패(Rejected) 둘 중 하나이다.
Resolve와 Reject 콜백이 있는 함수로, 새 Promise 인스턴스를 만들면 된다.
// jQuery의 ajax 통신
function getData(callbackFunc) {
$.get('url 주소/products/1', function(response) {
callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
});
}
getData(function(tableData) {
console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
});
// Promise의 ajax 통신
function getData(callback){
// new Promise() 추가
return new Promise(resolve, reject){
$api.get('url/products/1', function(response){
// 데이터를 받으면 resolve() 호출
resolve(response);
})
})
}
// getData()의 실행이 끝나면 호출되는 then()
getData().then(function(tableData){
// resolve()의 결과 값이 여기로 전달된다.
console.log(tableData);
}
프로미스 상태는 프로미스의 처리 과정을 의미하는데, 처리 과정은 new Promise()를 생성하고, 종료될 때까지 3가지 상태를 갖는다!
new Promise(Promise 생성자 함수)가 인자로 전달받은 콜백함수는, 내부에서 비동기처리 작업을 한다.
먼저 아래와 같이 new Promise()(생성자 함수) 메서드를 호출하면 대기(Pending) 상태가 된다.
new Promise()
new Promise()
메서드를 호출할 때 콜백함수를 선언할 수 있고, 콜백 함수의 인자는 resolve, reject이다.
new Promise(function(resolve, reject){
// ...
})
여기서 콜백 함수 인자 resolve를 아래와 같이 실행하면 성공(Fulfilled)상태가 된다.
new Promise(function(resolve, reject){
resolve();
}
그리고, 이행 상태가 되면 아래와 같이 then()
을 이용하여 처리 결과 값을 받을 수 있다.
function getData(){
return new Promise(function(resolve, reject){
var data = 100;
resolve(data);
})
}
// resolve()의 결과 값인 data를 resolveData로 받음
getData().then(function(resolveData){
console.log(resolveData); // 100
})
new Promise()(생성자 함수)로 프로미스 객체를 생성하면 콜백함수 인자로 resolve와 reject를 사용할 수 있다고 했다.
여기서 reject를 아래와 같이 호출하면 실패 상태가 된다.
new Promise(function(resolve, reject){
reject();
})
그리고, 실패 상태가 되면 실패한 이유(실패 처리의 결과값)을 catch()로 받을 수 있다.
function getData(){
return new Promise(function(resolve, reject){
reject(new Error('Request is Faild'));
})
}
// reject()의 결과 값 error를 error에 받는다.
getData().then().catch(function(error){
console.log(error); // Error: Request is failed
})
new Promise로 구현된 비동기 함수는 Promise 객체를 반환해야 한다. Promise로 구현된 비동기 함수를 호출하는 측에서는 Promise 객체의 후속 처리 메소드(then, catch)를 통해 비동기 처리 결과? 또는 에러 메세지를 전달 받아 처리한다.
Promise 객체는 상태를 갖기 때문에, 이 상태에 따라 후속 처리 메소드를 체이닝 방식으로 호출한다.
function getData(){
return new Promise(function(resolve, reject){
$.get('url 주소/products/1', function(response){
if(response){
resolve(response);
}
reject(new Error('Request is Faild'));
})
})
// $.get 호출 결과에 따라 response 또는 error 출력
getData().then(function(data){
console.log(data) // response 값 출력
}).catch(function(error){
console.error(error) // Error 출력
})
function getData(){
return new Promise({
// ...
})
}
// then() 으로 여러 개의 프로미스를 연결한 형식
getData()
.then(function(data){
// ...
})
.then(function(){
// ...
})
.then(function(){
// ...
})
.then(function(){
// ...
})
비동기 처리 예제에서 가장 흔하게 사용되는 setTimeout() API
new Promise(function(resolve, reject){
setTimeout(function(){
resolve(1)
}, 20000)
})
.then(function(result){
console.log(resulte);
return result + 10
})
.then(function(result){
console.log(result);
return result + 20
})
.then(function(result){
console.log(result);
})
실제 서비스를 구현하다 보면 네트워크 연결, 서버 문제 등으로 인해 오류가 발생할 수 있다.
Promise 에러 처리 방법에는 2가지 방법이 있다.
getData().then(handleSuccess, handleError);
getData().then().catch();
위 두가지 방법 모두 promise의 reject() 메서드가 호출되어 실패 상태가 된 경우에 실행된다.
가급적 catch()로 에러를 처리하는 게 더 효율적이다.
function getData(){
return new Promise((resolve, reject){
reject('failed');
})}
// 1. then()의 두 번째 인자로 에러를 처리하는 코드
getData().then(function(){
// ...
}, function(error){
console.log(error);
})
// 2. catch()로 에러를처리하는 코드
getData().then().catch(function(error){
console.error(error);
})