JavaScript에서 콜백(callback) 함수는 특정 코드의 실행이 완료된 후 실행되어야 할 함수를 말합니다. 콜백 함수는 주로 비동기 처리에서 사용됩니다. 하지만, 비동기 처리를 콜백으로만 관리할 경우, 코드의 중첩이 심해져 "콜백 지옥(Callback Hell)"이 발생할 수 있습니다. 이를 해결하기 위해 ES6부터는 Promise와 async/await가 도입되었습니다.
function step1(callback) {
setTimeout(() => {
console.log('첫 번째 작업 완료');
callback();
}, 1000);
}
function step2(callback) {
setTimeout(() => {
console.log('두 번째 작업 완료');
callback();
}, 1000);
}
step1(function() {
step2(function() {
console.log('모든 작업 완료');
});
});
첫 번째 작업 완료
두 번째 작업 완료
모든 작업 완료
콜백 지옥은 여러 개의 비동기 작업이 중첩되어 코드의 가독성과 관리가 어려워지는 현상을 말합니다. 각 단계마다 콜백 함수를 중첩하여 사용함으로써 발생합니다.
Promise는 비동기 작업의 최종 성공 또는 실패를 나타내는 객체입니다. then을 사용하여 성공 시의 처리와 catch를 사용하여 실패 시의 처리를 할 수 있습니다.
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('데이터 로딩 완료');
}, 1000);
});
}
fetchData().then(data => {
console.log(data);
}).catch(error => {
console.error(error);
});
데이터 로딩 완료
async/await는 Promise를 더 쉽게 사용할 수 있게 해주는 ES8(ES2017)의 문법입니다. async 함수는 항상 Promise를 반환하며, await는 Promise가 처리될 때까지 함수의 실행을 일시 중지합니다.
async function fetchData() {
return '데이터 로딩 완료';
}
async function main() {
const data = await fetchData();
console.log(data);
}
main();
결과값
데이터 로딩 완료
콜백 지옥은 코드의 가독성과 유지보수를 저하시킵니다. 가능하면 Promise나 async/await을 사용하여 해결하는 것이 좋습니다.
async/await 사용 시 에러 처리를 위해 try/catch 구문을 사용할 수 있습니다. 비동기 처리의 흐름을 이해하고 올바르게 관리하는 것이 중요합니다.
기능 | 콜백(Callback) | Promise | async/await |
---|---|---|---|
기본 개념 | 다른 함수에 인자로 전달되어 그 함수가 실행된 후 실행되는 함수. | 비동기 작업의 성공 또는 실패 결과를 나타내는 객체. | 비동기 작업을 동기 작업처럼 보이게 하는 문법. |
장점 | 단순하고 이해하기 쉬움. | 비동기 작업을 체인으로 연결하여 처리할 수 있음. | 코드가 동기적으로 보이며, 가독성이 좋음. |
단점 | 콜백 지옥으로 인한 가독성 저하. | 오류 처리가 번거로울 수 있음. | 최신 브라우저에서만 지원. |
콜백은 JavaScript의 오래된 비동기 처리 모델로, 간단한 비동기 작업에서 잘 작동합니다. 하지만 복잡한 비동기 처리에서는 코드의 중첩이 깊어지는 콜백 지옥이 발생할 수 있습니다. 이를 해결하기 위해 Promise
가 도입되었으며, Promise
는 비동기 작업을 연속적으로 처리할 때 유용합니다. 또한, async/await
는 Promise
기반의 비동기 처리 코드를 동기 처리처럼 간결하게 작성할 수 있게 해줍니다.