
다른 함수의 인자로 전달되는 함수이다.
function main(callback) {
callback();
}
main(function() {});
main(() => { });
위 코드에서는 main 함수의 인자로 전달된 함수가 바로 콜백함수이다.
비동기적으로 수행되는 작업은 정확히 언제 끝나는지 알기가 힘들다는 특징이 있다. 그래서, 코드의 실행 순서가 뒤죽박죽이 될 수 있다.
따라서 특정 비동기 작업이 끝나고 나서 명확하게 후처리를 해주기 위해, 콜백함수를 사용한다. 이러한 콜백함수를 비동기 콜백이라고 한다.
function getData() {
setTimeout(() => {
console.log("서버에서 데이터를 받아왔어요.");
}, 2000);
}
getData();
console.log("후처리..");
// "후처리.." "서버에서 데이터를 받아왔어요."
setTimeout()을 사용해서 네트워크 통신에 걸리는 시간을 흉내낸다. 서버에서 데이터를 받아오는데 2초가 걸린다고 가정한다. 위 코드는 후처리 코드가 네트워크 통신이 완료되는 것보다 먼저 수행이 된다.
getData() 함수가 끝난 다음에 후처리를 하는 코드가 호출 되도록 하려한다. 이때, 비동기 콜백을 사용한다.
function getData(callback) {
setTimeout(() => {
console.log("서버에서 데이터를 받아왔어요.");
callback({name: "성민"});
}, 2000);
}
getData((data) => {
console.log("data.name");
});
// "서버에서 데이터를 받아왔어요." "성민"
네트워크 통신이 완료된 다음에 콜백함수를 호출하여 후처리를 명확하게 해줄 수 있다. 콜백함수를 사용하면 비동기 작업이 완료된 후에 실행되어야 하는 코드를 명확하게 정의할 수 있다.
// 1. 로그인
function login(username, callback) {
setTimeout(() => {
callback(username);
}, 1000);
}
// 2. 장바구니에 넣기
function addToCart(product, callback) {
setTimeout(() => {
callback(product);
}, 1000);
}
// 3. 결제하기
function makePayment(cardNumber, product, callback) {
setTimeout(() => {
callback(cardNumber, product);
}, 1000);
}
login("min", (username) => {
console.log(`${username}님 안녕하세요.`);
addToCart("감자", ((product) => {
console.log(`${product}를 장바구니에 넣었습니다.`);
makePayment("0000000000000000", product, ((cardNumber, product) => {
console.log(`${cardNumber.slice(0,6)로 ${product}를 구매했습니다.`);
// ....
});
});
});
// "min님 안녕하세요." "감자를 장바구니에 넣었습니다." "000000로 감자를 구매했습니다."
※ 1초는 네트워크 통신 시간을 나타낸 것이다.
1, 2, 3번 작업은 모두 네트워크 통신을 해야 하기에 비동기적으로 동작한다. 그리고, 각 작업은 이전 작업에 의존한다. 다시말해, 로그인을 한 후에 장바구니에 넣고, 장바구니에 넣은 후에 결제를 해야한다. 따라서 비동기 콜백을 이용해서, 비동기 작업을 완료한 후 명확한 후처리를 해야한다.
비동기 콜백을 사용해서 비동기적으로 동작하는 세 가지의 함수(비동기 함수)를 순서대로 호출해줄 수 있다. 콜백함수를 사용해서 특정 비동기 작업이 완료되었을 때, 어떤 코드가 실행되어야 하는지 명확하게 정의할 수 있다.
login()을 호출하고, addToCart()를 호출하고, makePayment()를 호출하면서 코드가 복잡해진다. 굉장히 더럽고 지저분하다.
여러 개의 작업을 연달아서 수행하면서, 콜백 함수를 중첩시켰기에 코드의 가독성이 떨어진다. 유지보수에도 어려움을 준다. 바로 이러한 것을 콜백 지옥이라고 한다.
세 작업이 아니라 더 많은 비동기 작업을 연달아서 해야한다면 콜백 지옥은 더 깊어진다. 만약 결제가 된 후에 상품의 리뷰를 남겨야한다면 reviewProduct와 같은 콜백함수를 또 호출하면서 코드가 길어진다.
Promise를 사용해서 콜백지옥을 해결할 수 있다.