콜백 지옥 (callback hell)
콜백 함수를 통해 비동기 로직을 처리한 뒤 후속 결과를 가지고 다음 비동기 로직을 또 처리해야 하는 식으로 콜백 함수가 계속 중첩되었을 때 가독성이 떨어지고 코드 복잡도가 증가하는 현상
const promise = new Promise((resolve, reject) => {
if (비동기 처리 성공) {
resolve(결과);
} else { // 비동기 처리 실패
reject(실패 이유);
}
});
현재 비동기 처리가 어떻게 진행되고 있는지에 대한 상태 정보이다.
생성 직후의 프로미스는 기본적으로 pending 상태이며 비동기 처리가 완료(settled)된 후 결과가 성공인지 실패인지에 따라 fulfilled 또는 rejected 상태로 변경된다.
const fulfilled = new Promise((resolve) => resolve(1));
// 결과
// Promise {<fulfilled>: 1}
// [[ PromiseStatus ]]: "fulfilled"
// [[ PromiseValue ]]: 1
즉, 프로미스는 비동기 처리 상태와 비동기 처리 결과를 반환하는 객체이다.
프로미스의 처리 결과를 가지고 후속 처리 메서드를 진행한다.
이전의 콜백 패턴(콜백 헬)에서는 에러 처리가 곤란했지만 ES6이 도입한 프로미스는 에러를 효과적으로 처리할 수 있다.
const wrongUrl = 'https: //jsonplaceholder.typicode.com/XXX/1';
promiseGet(wrongUrl).then(
res => console.log(res), // 1번째 항: 성공 시 호출
err => console.log(err) // 2번째 항: 실패 시 호출
);
이 방법은 then의 두 번째 콜백 함수(err => ~)가 첫 번째 콜백 함수(res => ~)에서 발생한 에러를 캐치할 수 없고 코드 가독성도 떨어져서 좋지 않다.
const wrongUrl = 'https: //jsonplaceholder.typicode.com/XXX/1';
promiseGet(wrongUrl)
.then(res => console.log(res))
.catch(err => console.log(err));
);
catch는 내부적으로 then(undefined, onRejected) 형태로 호출되어 다음과 같이 처리된다.
promiseGet(wrongUrl)
.then(res => console.log(res))
.then(undefined, err => console.log(err)); // 원래 catch문
);
2번의 catch문 사용
catch 메서드를 모든 then 메서드를 호출한 후에 호출하면
위에서 살펴봤듯이 then, catch, finally 후속 메서드는 언제나 프로미스를 반환하기 때문에 결과 프로미스를 가지고 다음 후속 처리 메서드를 연이어 실행할 수 있다.
이를 프로미스 체이닝이라고 한다.
[
{ status: 'fulfilled', value: 1 },
{ status: 'rejected', reason: Error: Error! at <anonymous>:3:60 }
]