자바스크립트는 비동기 처리를 위한 하나의 패턴으로 콜백 함수를 사용하는데, 전통적인 콜백 패턴은 아래와 같은 몇가지 단점이 존재한다.
콜백 헬로 인해 가독성이 나쁘다.
get('/step1', a => {
get(`/step2/${a}`, b => {
get(`/step3/${b}`, c => {
get(`/step4/${c}`, d => {
console.log(d);
});
});
});
});
비동기 함수를 호출하면 함수 내부의 비동기로 동작하는 코드가 완료되지 않았다 해도 기다리지 않고 즉시 종료된다. 즉, 비동기 함수 내부의 비동기로 동작하는 코드는 비동기 함수가 종료된 이후에 완료된다.
let g = 0;
// 비동기 함수인 setTimeout 함수는 콜백 함수의 처리 결과를 외부로 반환하거나
// 상위 스코프의 변수에 할당하지 못한다.
setTimeout(() => { g = 100; }, 0);
console.log(g); // 0
✔️ 비동기 함수는 처리 결과를 외부에 반환할 수 없고, 상위 스코프의 변수에 할당할 수도 없기 때문에 비동기 함수의 처리 결과(서버 응답 등)에 대한 후속 처리는 비동기 함수 내부에서 수행해야 한다.
비동기 처리 중 발생한 에러의 처리가 곤란하다.
try {
setTimeout(() => { throw new Error('Error!'); }, 1000);
} catch (e) {
// 에러를 캐치하지 못한다
console.error('캐치한 에러', e);
}
✔️ setTimeout 함수의 콜백 함수가 실행될 때 setTimeout 함수는 이미 콜 스택에서 제거된 상태이고, 이는 setTimeout 함수의 콜백 함수를 호출한 것이 setTimeout 함수가 아니라는 의미이다. 에러는 호출자(caller) 방향으로 전파되기 때문에 setTimeout 함수의 콜백 함수가 발생시킨 에러는 catch 블록에서 캐치되지 않는다.
여러 개의 비동기 처리를 한번에 처리하는 데 한계가 있다.