콜백함수를 한두개만 쓰면 괜찮겠지만
이런식으로 함수를 작성한다고 생각해보자. disk4와 disk2의 순서를 변경해주거나 특정 함수만을 유지, 보수해야한다고 했을 때 정말 어려울 것이다. 또 내가 작성한 코드가 아니라 다른 사람이 작성한 저런 콜백함수를 내가 수정해야 한다고 하면 많으 어려움이 있을 것이다 .
그래서 나온 문법 Promise 문법이다.
프로미스는 비동기 작업을 조금 더 편하게 처리 할 수 있도록 ES6 에 도입된 기능이다.
const myPromise = new Promise((resolve, reject) => {
})
Promise는 다음과 같이 구현할 수 있다. 또한 Promise는 동작이 성공 할 수도 있고 실패할 수도 있는데 성공하면 resolve를 실패하면 reject를 받는다.
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1);
}, 1000);
});
myPromise.then(n => {
console.log(n);
});
또 작업이 끝나고 또 다른 작업을 할때는 .then을 붙여서 사용하면 된다.
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);
});
}
increaseAndPrint(0).then((n) => {
console.log('result: ', n);
})
이렇게 사용하면 된다.
하지만 여기까지만 봤을 때는 콜백함수보다 그렇게 좋은거 같지 않은데? 라는 생각이 들 수 있는데 then내부에 넣은 함수에서 또 Promise를 리턴하게 되면 연달아 사용할 수 있다.
increaseAndPrint(0) //프로미스
.then(n => {
return increaseAndPrint(n);
})
.then(n => {
return increaseAndPrint(n);
})
.then(n => {
return increaseAndPrint(n);
})
.then(n => {
return increaseAndPrint(n);
})
.then(n => {
return increaseAndPrint(n);
})
이러면 가독성 측면에서 매우 좋아진다.
또 이 코드는 이렇게 까지 쓸 수 있다.
increaseAndPrint(0)
.then(increaseAndPrint)
.then(increaseAndPrint)
.then(increaseAndPrint)
.then(increaseAndPrint)
.then(increaseAndPrint)
위에 콜백 지옥과 비교했을 때 정말 말도 안되게 가독성 측면에서 좋아졌고 작업의 개수가 많아도 코드의 깊이가 깊어지지 않아도 된다.
이렇게 좋아보이는 promise도 단점이 있다. 그 단점을 보완하기 위해서 나온 문법이 async await 문법인데 과연 promise는 뭐가 문제였을까?? 다음 편에서 그 문제점에 대해 알아보고 async await에 대해 공부해보자