13. 시간을 다루는 마법 (비동기 처리)/13.2 콜백 함수와 콜백 지옥

13.2.1 콜백 함수란? - 다른 함수에게 맡기는 특별한 임무

thejavascript4kids 2025. 7. 18. 03:53

📘 13.2.1 콜백 함수란? - 다른 함수에게 맡기는 특별한 임무

함수를 건네주는 마음

여러분, 다시 만나게 되었네요. 지금까지 setTimeout과 setInterval을 사용하면서 "나중에 실행할 기능"을 첫 번째 입력값으로 전달하는 것을 배웠어요. 그때마다 전달하던 그 기능이 바로 콜백 함수라는 특별한 이름을 가지고 있었답니다.

콜백 함수는 JavaScript에서 매우 소중한 개념이에요. "다른 함수에게 맡겨두고 나중에 실행해달라고 부탁하는 함수"를 의미해요. 마치 신뢰하는 친구에게 심부름을 맡기면서 "이 일을 해달라"고 메모지를 건네주는 것과 같아요.

🧠 새로운 단어들과 친해지기

함수를 다른 함수에게 전달하는 개념과 관련된 중요한 단어들을 정리해볼게요.

단어 의미
콜백 함수 (Callback Function) 다른 함수에 입력값으로 전달되어 나중에 실행되는 함수예요.
다른 함수 함수를 입력값으로 받거나 함수를 돌려주는 함수예요.
입력값 (Argument) 함수를 호출할 때 전달하는 값이나 함수예요.
나중에 처리하기 코드가 순서대로가 아니라 시간에 따라 실행되는 방식이예요.

콜백이라는 말은 "call back(다시 부르다)"에서 온 말로, 나중에 다시 불러달라고 맡겨두는 함수라는 뜻이에요.

✨ 콜백 함수의 핵심 개념

콜백 함수는 JavaScript의 가장 기본적이면서도 강력한 기능 중 하나예요. 함수를 마치 변수처럼 다른 함수에게 전달할 수 있다는 것이 JavaScript의 놀라운 특징이에요.

일상생활에서 비유하면, 친구에게 "내가 없을 때 택배가 오면 이 방법대로 처리해줘"라고 부탁하면서 처리 방법을 적은 메모지를 건네주는 것과 같아요. 여기서 메모지가 바로 콜백 함수예요. 친구(다른 함수)는 적절한 시점(택배가 올 때)에 그 메모지(콜백 함수)를 보고 처리하는 거죠.

이런 방식의 가장 큰 장점은 여러 가지로 활용할 수 있다는 것이에요. 같은 상황에서도 상황에 따라 다른 처리 방법을 선택할 수 있어요. 예를 들어, setTimeout은 시간만 담당하고, 실제로 무엇을 할지는 우리가 전달하는 콜백 함수가 결정해요.

레스토랑의 주문 시스템 이야기

콜백 함수를 이해하기 위해 하나의 이야기를 들려드릴게요.

레스토랑에 가서 음식을 주문할 때를 상상해보세요. 여러분은 주문을 하면서 동시에 "음식이 나오면 어떻게 할지"도 알려줘요. "음식이 나오면 테이블 5번으로 가져다주세요"라고 말하는 것처럼 말이에요.

여기서 주방(setTimeout)은 음식을 만드는 일을 담당하고, "테이블 5번으로 가져다주세요"라는 지시사항이 콜백 함수예요. 주방은 음식이 완성되는 적절한 시점에 그 지시사항을 실행해요.

만약 같은 음식을 주문하더라도 고객마다 다른 요청을 할 수 있어요. "포장해주세요", "테이블로 가져다주세요", "카운터에서 가져가겠어요" 등 다양한 콜백 함수를 전달할 수 있는 거죠.

setTimeout(기능, 3000)도 마찬가지예요. 타이머(주방)는 3초를 재는 일만 하고, 3초 후에 무엇을 할지는 우리가 전달한 기능(지시사항)이 결정해요. 이렇게 해서 같은 타이머 기능으로도 다양한 일을 할 수 있게 되는 거예요.

🎯 콜백 함수를 사용하는 이유

그렇다면 언제 콜백 함수를 사용하게 될까요?

코드를 다시 사용할 수 있어요. 같은 기능을 하는 함수에 다양한 콜백 함수를 전달해서 서로 다른 동작을 만들 수 있어요. 예를 들어, setTimeout은 시간을 재는 기능만 하지만, 다양한 콜백 함수를 전달해서 메시지 출력, 색상 변경, 애니메이션 등 무엇이든 할 수 있어요.

나중에 처리하기 위해서도 사용해요. 웹페이지에서는 여러 일이 동시에 일어나요. 사용자가 버튼을 클릭하거나, 타이머가 끝나거나, 서버에서 정보가 도착하는 등의 이벤트가 언제 일어날지 미리 알 수 없어요. 콜백 함수를 사용하면 "이런 일이 일어나면 이렇게 처리해줘"라고 미리 준비해둘 수 있어요.

이벤트 기반 프로그래밍을 위해서도 필요해요. 현대 웹 개발은 대부분 이벤트 중심으로 이루어져요. 사용자의 행동, 시간의 경과, 네트워크 응답 등 다양한 이벤트에 반응해서 적절한 처리를 하는 거죠. 콜백 함수는 이런 이벤트 처리의 핵심 도구예요.

유연한 실행 순서를 만들기 위해서도 활용해요. 전통적인 프로그래밍에서는 위에서 아래로 순서대로 실행되지만, 콜백 함수를 사용하면 필요에 따라 실행 순서를 자유롭게 조절할 수 있어요.

⚙️ 기본 사용법 배우기

콜백 함수의 기본 사용법은 다른 함수에 함수를 전달하는 거예요. 생각보다 간단해요.

// 기본 형태
함수이름(콜백함수, 기타입력값들);

// 실제 예시
setTimeout(myFunction, 2000);

함수를 전달하는 다양한 방법:

// 방법 1: 미리 만든 함수 전달
function sayHello() {
    console.log("안녕하세요!");
}
setTimeout(sayHello, 1000);

// 방법 2: 화살표 함수로 바로 전달
setTimeout(() => {
    console.log("안녕하세요!");
}, 1000);

// 방법 3: 이름 없는 함수로 전달
setTimeout(function() {
    console.log("안녕하세요!");
}, 1000);

중요한 주의사항:

함수를 전달할 때는 함수 이름 뒤에 괄호 ()를 붙이지 않아요. 괄호를 붙이면 함수가 즉시 실행되어서 그 결과가 전달되기 때문이에요. 우리가 원하는 것은 함수 자체를 전달하는 거예요.

🧪 직접 해보면서 배우기

이제 실제 예시를 통해서 콜백 함수가 어떻게 작동하는지 자세히 살펴볼게요.

🔹 첫 번째 예시: 기본적인 콜백 함수 사용

첫 번째 예시에서는 가장 기본적인 콜백 함수 사용법을 배워볼게요.

// 나중에 실행될 콜백 함수를 미리 만들어요
function showWelcomeMessage() {
    console.log("환영해요!"); // 환영 메시지를 출력해요
    console.log("3초 동안 기다려주셔서 감사해요."); // 감사 메시지를 출력해요
}

// showWelcomeMessage 함수를 콜백으로 setTimeout에 전달해요
setTimeout(showWelcomeMessage, 3000); // 3초 후에 실행하도록 예약해요

// 이 메시지들은 즉시 출력돼요
console.log("3초 후에 환영 메시지가 나타날 예정이에요."); // 바로 실행되는 안내 메시지
console.log("잠시만 기다려주세요..."); // 바로 실행되는 대기 메시지

이 과정을 천천히 살펴보면, 먼저 나중에 실행하고 싶은 작업을 함수로 만들어요. 그다음 그 함수를 setTimeout에 콜백으로 전달하죠. 중요한 점은 함수 이름 뒤에 괄호를 붙이지 않는다는 거예요. 바로 실행되는 메시지들이 먼저 출력되고, 3초 후에 콜백 함수가 실행되어 환영 메시지가 나타나요.

🔹 두 번째 예시: 화살표 함수를 콜백으로 사용하기

두 번째 예시에서는 화살표 함수를 사용해서 더 간결하게 콜백 함수를 작성하는 방법을 배워볼게요.

// 사용자 이름을 저장하는 변수예요
let userName = "지민";

// 화살표 함수를 사용해서 콜백 함수를 바로 작성해요
setTimeout(() => {
    console.log(userName + "님, 안녕하세요!"); // 개인화된 인사말을 출력해요
    console.log("오늘도 좋은 하루 되세요!"); // 응원 메시지를 출력해요
}, 2000); // 2초 후에 실행하도록 예약해요

// 반복 타이머에서도 화살표 함수 콜백을 사용할 수 있어요
setInterval(() => {
    console.log("현재 시간: " + new Date().toLocaleTimeString()); // 현재 시간을 5초마다 출력해요
}, 5000); // 5초마다 반복 실행해요

console.log("타이머들이 설정되었어요!"); // 바로 실행되는 확인 메시지

이 예시에서는 따로 함수를 만들지 않고 화살표 함수를 사용해서 콜백을 바로 작성했어요. 이 방법은 간단한 콜백 함수를 만들 때 매우 편리해요. 또한 콜백 함수 내부에서 외부 변수(userName)에 접근하는 것도 확인할 수 있어요.

🔹 세 번째 예시: 조건부 콜백 함수 활용하기

세 번째 예시에서는 콜백 함수 내부에서 조건을 확인하고 다양한 동작을 하는 방법을 배워볼게요.

// 현재 시간을 확인해서 다른 인사말을 하는 콜백 함수예요
let currentHour = new Date().getHours(); // 현재 시간을 가져와요

setTimeout(() => {
    console.log("현재 시간은 " + currentHour + "시예요."); // 현재 시간을 출력해요

    // 시간대에 따라 다른 메시지를 출력해요
    if (currentHour < 12) {
        console.log("좋은 아침이에요! ☀️"); // 오전 인사말
    } else if (currentHour < 18) {
        console.log("좋은 오후예요! 🌤️"); // 오후 인사말
    } else {
        console.log("좋은 저녁이에요! 🌙"); // 저녁 인사말
    }

    console.log("즐거운 시간 보내세요!"); // 공통 응원 메시지
}, 1000); // 1초 후에 실행해요

console.log("1초 후에 시간에 맞는 인사를 드릴게요!"); // 바로 실행되는 안내 메시지

이 예시에서는 콜백 함수 내부에서 현재 시간을 확인하고, 시간대에 따라 다른 인사말을 출력해요. 이처럼 콜백 함수는 단순히 메시지를 출력하는 것을 넘어서 복잡한 논리를 포함할 수도 있어요. 조건문을 사용해서 상황에 맞는 적절한 처리를 할 수 있어요.

🔄 콜백 함수 사용하는 순서 정리하기

지금까지 학습한 콜백 함수의 사용 단계를 자연스럽게 정리해볼게요.

첫 번째 단계는 콜백 함수 준비예요. 나중에 실행하고 싶은 작업을 함수로 만들거나, 화살표 함수로 준비해요. 이때 어떤 작업을 언제 실행할지 명확히 계획하는 것이 중요해요.

두 번째는 다른 함수 선택 단계예요. 콜백 함수를 받을 수 있는 함수(setTimeout, setInterval 등)를 선택하고, 그 함수가 어떤 방식으로 콜백을 사용하는지 이해해요.

세 번째는 콜백 전달 단계예요. 준비한 함수를 다른 함수의 입력값으로 전달해요. 이때 함수 이름 뒤에 괄호를 붙이지 않도록 주의해야 해요.

네 번째는 실행 대기 단계예요. 콜백을 받은 함수가 자신의 작업을 수행하면서, 적절한 시점까지 콜백 함수를 보관하고 기다려요.

마지막 단계는 콜백 실행이에요. 정해진 시점이나 조건이 만족되면, 보관해두었던 콜백 함수가 자동으로 실행돼요. 이 과정은 자동으로 일어나므로 별도로 신경 쓸 필요가 없어요.

🏢 이야기로 다시 배우기: 우리 학교의 부탁 전달 시스템

지금까지 배운 내용을 하나의 이야기로 다시 정리해볼까요?

우리 학교에는 특별한 "부탁 전달" 시스템이 있어요. 학생들이 다른 학생에게 부탁을 할 때 사용하는 효율적인 방법이에요.

예를 들어, 수연이가 민수에게 "3시간 후에 도서관에서 만나자"라고 부탁하고 싶다면, 다음과 같은 과정을 거쳐요:

  1. 수연이는 "3시간 후에 할 일"을 적은 메모지를 준비해요. "도서관 3층에서 만나서 함께 과제하기"라고 적혀있어요.

  2. 수연이는 학급 시간 담당에게 가서 "3시간 후에 이 메모지대로 해주세요"라고 부탁을 건네줘요.

  3. 시간 담당은 부탁을 받아서 학급 일정표에 보관해요. "3시간 후에 이 메모지를 실행하겠다"고 약속하죠.

  4. 3시간이 지나면, 시간 담당은 자동으로 메모지를 꺼내서 읽고 실행해요. 민수에게 알림을 보내서 도서관으로 부르는 거죠.

이 이야기에서 "3시간 후에 할 일"을 적은 메모지가 바로 콜백 함수예요. 시간 담당(setTimeout)은 시간만 재고, 실제로 무엇을 할지는 메모지(콜백 함수)가 결정하는 거예요.

다른 학생들도 같은 시간 담당에게 서로 다른 메모지를 맡길 수 있어요. "친구에게 생일 축하 메시지 보내기", "교실 청소하기", "선생님께 숙제 제출하기" 등 다양한 부탁을 할 수 있죠. 시간 담당은 시간 재기만 담당하고, 구체적인 일은 각각의 메모지(콜백 함수)가 담당하는 유연하고 똑똑한 시스템이에요!

🧠 자주 하는 실수와 주의할 점

콜백 함수를 사용할 때 주의해야 할 몇 가지 실수들을 미리 알아두면 더 안전하게 사용할 수 있어요.

❌ 실수 1: 함수를 호출해서 결과를 전달하기

// 잘못된 방법 - 함수를 즉시 실행해버림
function greet() {
    console.log("안녕하세요!");
    return "인사 완료";
}
setTimeout(greet(), 2000); // greet()의 결과인 "인사 완료"가 전달돼요

// 올바른 방법 - 함수 자체를 전달
setTimeout(greet, 2000); // greet 함수 자체가 전달돼요

이런 실수가 발생하는 이유는 괄호 ()가 있으면 함수가 즉시 실행되기 때문이에요. 콜백으로는 함수의 실행 결과가 아니라 함수 자체를 전달해야 해요.

❌ 실수 2: 함수 이름을 문자열로 전달하기

// 잘못된 방법 - 함수 이름을 문자열로 전달
setTimeout("myFunction", 1000); // 문자열로 전달하면 안 돼요

// 올바른 방법 - 함수 자체를 전달
function myFunction() {
    console.log("정상 실행!");
}
setTimeout(myFunction, 1000); // 함수 자체를 전달해요

함수 이름을 따옴표로 감싸서 문자열로 만들면 안 돼요. JavaScript는 문자열과 함수를 구분해서 처리하므로, 반드시 함수 자체를 전달해야 해요.

❌ 실수 3: this 키워드 사용 시 주의 부족

// 예상과 다르게 동작할 수 있는 코드
let person = {
    name: "철수",
    greet: function() {
        console.log(this.name + "님 안녕하세요!"); // this가 예상과 다를 수 있어요
    }
};

setTimeout(person.greet, 1000); // this가 person이 아닐 수 있어요

// 안전한 방법 - 화살표 함수나 변수 사용
setTimeout(() => {
    console.log(person.name + "님 안녕하세요!");
}, 1000);

this 키워드는 콜백 함수에서 예상과 다르게 동작할 수 있어요. 초보자라면 this 대신 변수를 직접 사용하거나 화살표 함수를 사용하는 것이 안전해요.

✏️ 연습문제로 개념 다지기

잠시 멈춰 서서, 마치 편지를 쓰듯 차근차근 문제를 풀어보세요. 함수를 다른 함수에게 전달하는 이 작은 행위 안에는 신뢰와 기대가 담겨 있어요.

Ex1) "좋은 하루 되세요!"라는 메시지를 3초 후에 출력하는 콜백 함수를 작성해보자

// 콜백 함수를 미리 만들고 setTimeout에 전달해요
function sayGoodDay() {
    console.log("좋은 하루 되세요!"); // 3초 후에 실행될 메시지
}

setTimeout(sayGoodDay, 3000); // 함수 이름만 전달 (괄호 없이)

이 연습을 통해 콜백 함수의 가장 기본적인 사용법을 익힐 수 있어요.

Ex2) 화살표 함수를 사용해서 1초마다 "틱톡"을 출력해보자

// 화살표 함수를 콜백으로 사용해서 반복 실행해요
setInterval(() => {
    console.log("틱톡"); // 1초마다 실행될 메시지
}, 1000); // 1초 = 1000밀리초

이 문제는 화살표 함수를 콜백으로 사용하는 방법을 연습하는 데 도움이 돼요.

Ex3) 변수를 사용하는 콜백 함수를 만들어보자. 좋아하는 음식 이름을 변수에 저장하고, 2초 후에 그 음식을 주문했다는 메시지를 출력해보자

// 좋아하는 음식을 변수에 저장해요
let favoriteFood = "피자";

// 2초 후에 주문 메시지를 출력하는 콜백 함수를 작성해요
setTimeout(() => {
    console.log(favoriteFood + "를 주문했어요!"); // 변수를 사용한 메시지 출력
}, 2000); // 2초 후에 실행

이 연습문제를 통해 콜백 함수에서 외부 변수를 사용하는 방법을 배울 수 있어요.

🤔 심화 문제로 실력 확인하기

기본 연습을 마쳤다면, 이제 조금 더 깊이 있는 문제들을 통해 콜백 함수에 대한 이해를 확인해보겠어요.

Q1. 다음 코드에서 콜백 함수는 무엇이고, 언제 실행될까요?

function sayGoodMorning() {
    console.log("좋은 아침이에요!");
}

setTimeout(sayGoodMorning, 5000);

정답: sayGoodMorning이 콜백 함수이고, 5초 후에 실행돼요.

해설: setTimeout에 전달된 함수가 콜백 함수예요. 5000밀리초(5초) 후에 자동으로 호출되어 "좋은 아침이에요!"를 출력해요.

Q2. 다음 코드의 실행 순서를 예측해보세요.

console.log("첫 번째");

setTimeout(() => {
    console.log("두 번째");
}, 0);

console.log("세 번째");

정답: "첫 번째" → "세 번째" → "두 번째" 순서로 출력돼요.

해설: setTimeout은 시간이 0이어도 현재 실행 중인 모든 코드가 끝난 후에 실행돼요. 따라서 콘솔 출력들이 먼저 모두 실행되고, 그 후에 콜백 함수가 실행돼요.

🔙 지난 시간 복습하기 (13.1.2 - setInterval)

13.2.1을 계속 공부하기 전에, 지난 시간에 배운 setInterval 내용을 복습해볼까요?

복습 문제 1: setInterval과 setTimeout의 차이

다음 중 setInterval에 대한 설명으로 올바른 것은?

// A) 한 번만 실행되고 끝남
// B) 정해진 간격마다 계속 반복 실행됨
// C) 콜백 함수를 사용할 수 없음
// D) 시간을 밀리초가 아닌 초 단위로 설정함

정답: B) 정해진 간격마다 계속 반복 실행됨

설명: 13.1.2에서 배운 setInterval은 setTimeout과 달리 한 번 설정하면 정해진 간격마다 계속해서 반복 실행되는 기능이에요. clearInterval로 멈추기 전까지 계속 반복돼요.

복습 문제 2: clearInterval 사용법

다음 코드에서 빈칸에 들어갈 올바른 내용은?

let timer = setInterval(() => {
    console.log("반복 중...");
}, 1000);

// 5초 후에 반복을 멈추고 싶다면?
setTimeout(() => {
    _______(timer);
}, 5000);

정답: clearInterval

설명: setInterval로 시작한 반복 타이머를 멈추려면 clearInterval을 사용해야 해요. 타이머 번호를 전달해서 특정 타이머를 멈출 수 있어요.

지금까지 콜백 함수의 모든 특성과 활용법을 자세히 알아보았어요. 콜백 함수는 JavaScript 프로그래밍의 핵심 개념으로, 함수를 마치 값처럼 다룰 수 있게 해주는 강력한 기능이에요. 마치 친구에게 심부름을 맡기듯이, 다른 함수에게 "이 일을 나중에 해줘"라고 부탁할 수 있게 해주는 유용한 도구랍니다!

✅ 학습 완료 체크리스트

이번 시간에 배운 내용들을 모두 이해했는지 확인해보세요!

학습 내용 이해했나요?
콜백 함수의 기본 개념
기본 사용법과 문법
레스토랑 비유 이해하기
자주 하는 실수들
실전 예제 활용하기

🎯 추가 연습 문제들

조금 더 연습하고 싶은 분들을 위한 추가 문제들이에요!

추가 문제 1. "안녕히 가세요!"라는 메시지를 3초 후에 출력하는 콜백 함수를 만드세요.

function goodbye() {
    console.log("안녕히 가세요!");
}

setTimeout(goodbye, 3000);

설명: 함수를 미리 정의하고 setTimeout에 전달해요.

추가 문제 2. 화살표 함수를 사용해서 1초마다 "틱톡"을 출력하세요.

setInterval(() => {
    console.log("틱톡");
}, 1000);

설명: 화살표 함수를 콜백으로 사용해서 반복 실행해요.

추가 문제 3. 변수를 사용하는 콜백 함수를 만들어보세요.

let food = "떡볶이";

setTimeout(() => {
    console.log(food + "를 주문했어요!");
}, 2000);

설명: 외부 변수를 콜백 함수 내부에서 사용할 수 있어요.

추가 문제 4. 다음 코드에서 콜백 함수는 무엇인가요?

function sayGoodMorning() {
    console.log("좋은 아침이에요!");
}

setTimeout(sayGoodMorning, 5000);

정답: sayGoodMorning
해설: setTimeout에 전달된 함수가 콜백 함수입니다. 5초 후에 실행될 예정입니다.

추가 문제 5. 다음 코드의 실행 순서를 예측해보세요.

console.log("첫 번째");

setTimeout(() => {
    console.log("두 번째");
}, 0);

console.log("세 번째");

정답: 첫 번째 → 세 번째 → 두 번째
해설: setTimeout은 시간이 0이어도 현재 코드가 모두 끝난 후에 실행됩니다.

📂 마무리 정보

오늘 배운 13.2.1 내용이 여러분의 자바스크립트 지식에 잘 저장되었나요? 다음 시간에는 더 재미있는 내용으로 만나요!

기억할 점: 오늘 배운 내용을 꼭 연습해보시고, 궁금한 점이 있으면 언제든 다시 돌아와서 읽어보세요.


🚀 더 체계적인 JavaScript 학습을 원하신다면?
이 포스팅에서 다룬 내용을 실제로 실습해보세요!
무료 JavaScript 학습 플랫폼에서 단계별 학습과 실시간 코드 실행을 통해
더욱 효과적이고 재미있게 학습하실 수 있습니다.
📝 실시간 코드 실행 📊 학습 진도 관리 👥 체계적 커리큘럼
📚 171개 체계적 학습레슨 · 📋 855개 4지선다 연습문제 · 🆓 완전 무료 · ⚡ 즉시 시작