Promise는 콜백지옥 현상을 해결하기 위해 등장한 패턴입니다!
Promise가 나오기 전까지는 콜백이 중첩될 때마다 복잡해지고 가독성을 해지는 일이 많아져서 콜백지옥에 빠지는 현상이 많았습니다.
이런 문제를 해결하고 또 비동기 작업을 조금 더 편하게 처리할 수 있도록 도입되었습니다.
기존 비동기 처리(콜백 지옥)
파라미터로 n을 받아 setTimeout으로 5번에 걸쳐 1초마다 1씩 더하여 출력하는 코드입니다.
코드의 깊이가 너무 깊어 가독성이 좋지 않고 복잡합니다.
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 비동기 처리
Promise를 사용하면 비동기 작업의 개수가 많아져도 코드의 깊이가 깊어지지 않게 된다.
function increaseAndPrint(n) {
return new Promise((resolve, reject)=>{
setTimeout(() => {
const increased = n + 1;
console.log(increased);
resolve(increased);
}, 1000)
})
}
increaseAndPrint(0)
.then((n) => increaseAndPrint(n))
.then((n) => increaseAndPrint(n))
.then((n) => increaseAndPrint(n))
.then((n) => increaseAndPrint(n)); // 체이닝 기법
Promise
Promise는 비동기 작업이 완료된 이후에 다음 작업을 연결시켜 진행할 수 있습니다.
const promise = new Promise((resolve, reject) => {
try {
...비동기 작업
resolve(결과);
} catch (err) {
reject(err);
}
});
Promise는 위와 같이 만들 수 있습니다.
작업결과에 따라 성공 또는 실패를 리턴하면 결과 값을 전달 받습니다.
성공하면 resolve를 호출해주고, 실패하면 reject를 호출해줍니다.
Promise의 객체는
promise.then((result) => {
// result 처리
}).catch((err) => {
console.error(err);
});
여기서 then과 catch로 받습니다. resolve의 결과 값은 then의 result로 , reject의 err은 catch의 err로 갑니다.
예시
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1);
}, 1000);
});
myPromise.then(n => {
console.log(n);
});
1초 뒤에 성공시키는 상황에 대해 구현한 코드인데
resolve를 호출할 때 특정 값 (여기서는 1)을 파라미터로 넣어주면 이 작업이 끝나고 사용할 수 있습니다.
다음 작업을 할 때에는 .then()을 사용하고 then의 콜백함수의 인자로 1을 받을 수 있습니다.
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);
})
Promise의 단점
- 에러를 잡을 때 몇번째에서 발생했는지 알아내기 어렵다.
- 특정 조건에 따라 분기를 나누기 어렵다.
- 특정 값을 공유해가면서 작업을 처리하기 어렵다.
참고자료 :https://velog.io/@ljinsk3/JavaScript-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%B2%98%EB%A6%AC-Promise-%EA%B0%9D%EC%B2%B4