Promise 객체는 자바스크립트 비동기 처리에 사용하는 객체이다.
Promise 객체를 통해 비동기 처리가 이루어지는 과정을 정리해 보려고 한다.
비동기로 처리한 작업이 완료 된 후 실행시킬 함수를 정의하는 데에는 Callback 함수를 이용하는 방법과 Promise 객체를 사용하는 방법이 있다.
(async/await도 promise객체를 사용함, then을 통해 호출 하지 않을 뿐!)
여러개의 함수를 순서대로 호출해야 하는 경우 Callback 함수를 사용 할 경우
아래와 같이 callback 지옥에 빠질 수 있다.
[ 중첩된 callback ]
function increaseAndPrint(n, callback) {
setTimeout(() => {
const increased = n + 1;
console.log(increased);
if (callback) {
callback(increased);
}
}, 1000);
}
increaseAndPrint(0, n => {
increaseAndPrint(n, n => {
increaseAndPrint(n, n => {
increaseAndPrint(n, n => {
increaseAndPrint(n, n => {
console.log('끝!');
});
});
});
});
});
이러한 상황을 방지하기 위해 Promise 객체를 사용한다.
생성자의 인자로 resolve, reject를 갖게 된다. (각각 함수이다.)
const getData = () =>{
new Promise((resolve, reject) => {
//pending 상태
//... 비동기 처리 ( data를 return 한다고 가정)
if(data) resolve(data); // fulfilled 상태
reject(new Error("Request is failed")); // rejected 상태
});
}
getData()
.then((data) => {
console.log(data); // data 출력
})
.catch((err) => {
console.error(err); // Error 출력
})
.finally(() => {
console.log('end'); // 무조건 실행
});
;
new Promise() 로 객체를 생성하고 종료될 때까지 3가지 상태를 갖는다.
Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태
생성자를 통해 Promise 객체를 만드는 순간 Pending(대기) 상태가 된다.
executor함수 인자중 하나인 resolve함수를 실행하면, fulfilled(이행) 상태가 된다.
fulfilled 상태가 되면 .then() 안에 작성한 CallBack함수를 실행한다.
executor함수 인자중 하나인 reject함수를 실행하면, rejected(거부) 상태가 된다.
rejected 상태가 되면 .catch() 안에 작성한 CallBack함수를 실행한다.
resolve() 함수나 reject() 함수에 인자를 넣으면 콜백 함수에서 사용할 수 있다.
function increaseAndPrint(n) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const value = n + 1;
if (value === 5) {
const error = new Error();
error.name = 'ValueIsFiveError';
reject(error);
return;
console.log(value);
resolve(value);
}, 1000);
});
}
//.then()을 이용해 여러개의 프로미스를 연결한 것을 Promise chaining 이라고도 한다.
increaseAndPrint(0)
.then(increaseAndPrint)
.then(increaseAndPrint)
.then(increaseAndPrint)
.then(increaseAndPrint)
.then(increaseAndPrint)
.catch(e => {
console.error(e);
});