콜백 패턴의 가장 심각한 단점은 에러 처리가 곤란하다는 것. 에러는 호출자 방향(콜 스택의 아래 방향)으로 전파되는데 비동기 함수의 콜백 함수를 호출한 것은 비동기 함수가 아니기 때문에 try ... catch 문을 사용해 에러를 캐치할 수 없다.
try {
setTimeout(() => { throw new Error('에러!'); }, 1000);
} catch (e) {
// 에러를 캐치하지 못한다
console.error('캐치하지못함', e);
}
- async 함수 내부에서 try ... catch문 사용
- async 함수 내부에서 에러처리하지않으면 에러를 reject하는 프로미스를 반환한다. 이때 반환한 프로미스를 후속처리메서드 catch로 에러를 캐치할 수 있다.
// 1
const foo = async () => {
try {
const wrongUrl = 'https://wrong.url';
const response = await fetch(wrongUrl)
const response = await response.json();
console.log(data)
} catch (err) {
console.error(err);// TypeError: Failed to fetch
}
};
foo();
// 2
const foo = async () => {
const wrongUrl = 'https://wrong.url';
const response = await fetch(wrongUrl)
const response = await response.json();
return data;
};
foo()
.then(console.log)
.catch(console.error);// TypeError: Failed to fetch
- then 메서드에 전달된 두번째 인수의 콜백함수로 처리
- 단점: 비동기 처리에서 발생한 에러(rejected)만 캐치할 수 있고, 자기자신(then 메서드) 내부에서 발생한 에러는 캐치할 수 없다.
- catch 메서드를 사용해 처리
- catch 메서드를 호출하면 내부적으로
then(undefined, onRejected)
을 호출한다. - 비동기 처리에서 발생한 에러(rejected) + then 메서드 내부에서 발생한 에러까지 모두 캐치할 수 있다.