📘 13.2.2 콜백 지옥 문제점 - 끝없는 미로 같은 코드들
완벽하지 않은 완벽함에 대하여
여러분, 다시 인사드려요. 지난 시간에 콜백 함수가 얼마나 유용한지 함께 알아보았죠. 다른 함수에게 "나중에 이 일을 해달라"고 맡길 수 있는 그 편리함에 감탄했었어요. 하지만 세상에는 완벽한 것이 없다고 했나요. 콜백 함수에도 깊은 그림자가 하나 있어요.
바로 콜백 지옥이라는 현상이에요. 순서대로 해야 할 일이 많아질수록 콜백 함수들이 끝없이 중첩되어, 마치 출구가 보이지 않는 미로처럼 복잡하고 아름답지 않은 코드가 만들어지는 거예요.
🧠 새로운 단어들과 친해지기
코드가 복잡해지는 현상과 관련된 중요한 단어들을 정리해볼게요.
단어 | 의미 |
---|---|
콜백 지옥 (Callback Hell) | 콜백 함수가 너무 많이 겹쳐서 코드가 읽기 어려워지는 문제예요. |
중첩 (Nesting) | 코드 블록 안에 또 다른 코드 블록이 들어가는 구조예요. |
읽기 쉬움 (Readability) | 코드를 읽고 이해하기 쉬운 정도를 나타내요. |
들여쓰기 (Indentation) | 코드의 구조를 보기 쉽게 하기 위해 앞부분에 공백을 넣는 거예요. |
콜백 지옥은 "callback(콜백)"과 "hell(지옥)"이 합쳐진 말로, 콜백 함수들이 너무 복잡하게 얽혀서 마치 지옥처럼 빠져나오기 어려운 상황을 의미해요.
✨ 콜백 지옥의 핵심 개념
콜백 함수는 분명 훌륭한 기능이지만, "순서대로 여러 일을 해야 하는 상황"에서는 큰 그림자를 드리워요. 예를 들어, "A를 한 후 → B를 하고 → 그 다음 C를 하고 → 마지막에 D를 해야 한다"는 상황을 떠올려보세요.
콜백 함수로 이를 만들려면 다음과 같은 구조가 되어버려요: A를 하는 함수 안에 B를 하는 콜백을 넣고, B를 하는 콜백 안에 C를 하는 콜백을 넣고, C를 하는 콜백 안에 D를 하는 콜백을 넣는 거죠. 이렇게 하면 함수 안에 함수, 그 안에 또 함수가 계속 들어가면서 코드가 계단 모양으로 오른쪽으로 계속 밀려나게 돼요.
이런 구조의 문제점은 여러 가지예요. 첫째, 코드를 읽기가 매우 어려워져요. 어디서 시작해서 어디서 끝나는지, 어떤 순서로 실행되는지 파악하기 힘들어요. 둘째, 코드를 바꾸기가 어려워져요. 중간에 새로운 단계를 추가하거나 순서를 바꾸려면 여러 곳을 동시에 고쳐야 해요. 셋째, 에러가 발생했을 때 어디서 문제가 생겼는지 찾기 어려워져요.
끝없는 러시아 인형 이야기
콜백 지옥을 이해하기 위해 하나의 이야기를 들려드릴게요.
러시아 인형은 인형 안에 더 작은 인형이 들어있고, 그 안에 또 더 작은 인형이 들어있는 구조로 유명해요. 처음에는 신기하고 재미있지만, 인형이 너무 많이 중첩되어 있으면 어떨까요?
가장 안쪽 인형에 무엇이 들어있는지 확인하려면 바깥 인형부터 하나씩 차례대로 열어야 해요. 10개, 20개의 인형이 중첩되어 있다면? 원하는 것을 찾기 위해 엄청나게 많은 단계를 거쳐야 하고, 중간에 실수라도 하면 다시 처음부터 시작해야 해요.
더 큰 문제는 인형을 다시 조립할 때예요. 어떤 순서로 어떻게 넣어야 하는지 헷갈리기 쉽고, 하나라도 빠뜨리거나 순서를 바꾸면 전체가 엉망이 되어버려요.
콜백 지옥도 정확히 이와 같아요. 함수 안에 함수, 그 안에 또 함수가 계속 들어가면서 마치 끝없는 러시아 인형처럼 복잡해져요. 원하는 부분을 찾거나 고치려면 여러 단계를 거쳐야 하고, 실수하기도 쉬워지는 거죠.
🎯 콜백 지옥을 이해해야 하는 이유
그렇다면 왜 콜백 지옥에 대해 배워야 할까요? 여러 중요한 이유가 있어요.
문제를 인식하기 위해서예요. 콜백 지옥이 무엇인지, 왜 문제가 되는지 알아야 더 나은 해결책을 찾고 싶어져요. 문제를 모르면 해결책의 가치도 모르게 되거든요.
실제 개발에서 자주 만나는 현실이기 때문이에요. 웹 개발을 하다 보면 "서버에서 정보를 가져온 후 → 그 정보를 처리하고 → 처리 결과를 화면에 보여주고 → 사용자에게 알림을 보내는" 등의 순차적 작업이 매우 많아요. 콜백만으로 이런 일들을 처리하려고 하면 콜백 지옥에 빠지기 쉬워요.
더 좋은 방법들의 필요성을 이해하기 위해서도 중요해요. 앞으로 배울 Promise, async/await 같은 기능들이 왜 등장했는지, 왜 중요한지를 알려면 먼저 콜백 지옥의 아픔을 이해해야 해요.
코드 품질에 대한 감각을 기르기 위해서도 필요해요. 좋은 코드와 아름답지 않은 코드를 구분할 수 있는 안목을 기르는 것은 프로그래밍 실력 향상에 매우 중요해요.
⚙️ 콜백 지옥의 구조 살펴보기
콜백 지옥이 어떤 모습인지 구체적으로 살펴볼게요. 기본적인 패턴은 다음과 같아요.
// 콜백 지옥의 전형적인 모습
첫번째함수(() => {
두번째함수(() => {
세번째함수(() => {
네번째함수(() => {
// 계속해서 더 깊어짐...
});
});
});
});
콜백 지옥의 특징들:
가장 눈에 띄는 특징은 계단 모양의 들여쓰기예요. 코드가 오른쪽으로 계속 밀려나면서 삼각형이나 피라미드 모양을 만들어요. 두 번째 특징은 닫는 괄호의 연속이에요. 함수가 끝날 때마다 });
가 반복되어 어디서 어떤 함수가 끝나는지 파악하기 어려워요.
세 번째 특징은 변수 범위의 복잡성이에요. 바깥쪽 함수의 변수를 안쪽에서 사용할 수 있지만, 중첩이 깊어질수록 어떤 변수가 어디서 온 것인지 헷갈리기 쉬워요.
🧪 직접 해보면서 배우기
이제 실제 예시를 통해서 콜백 지옥이 어떤 모습인지, 왜 문제가 되는지 자세히 살펴볼게요.
🔹 첫 번째 예시: 간단한 콜백 지옥 경험하기
첫 번째 예시에서는 순서대로 실행되는 간단한 작업들이 어떻게 콜백 지옥을 만드는지 확인해볼게요.
// 1초 → 2초 → 3초 순서로 메시지를 출력하는 작업
console.log("작업 시작!"); // 바로 실행되는 시작 메시지
// 첫 번째 작업: 1초 후 실행
setTimeout(() => {
console.log("1초 후: 첫 번째 작업이 완료되었어요!"); // 1초 후에 실행될 메시지
// 두 번째 작업: 첫 번째 작업 후 1초 더 기다림
setTimeout(() => {
console.log("2초 후: 두 번째 작업이 완료되었어요!"); // 2초 후에 실행될 메시지
// 세 번째 작업: 두 번째 작업 후 1초 더 기다림
setTimeout(() => {
console.log("3초 후: 세 번째 작업이 완료되었어요!"); // 3초 후에 실행될 메시지
console.log("🎉 모든 작업이 성공적으로 끝났어요!"); // 모든 작업 완료 메시지
}, 1000); // 1초 = 1000밀리초
}, 1000); // 1초 = 1000밀리초
}, 1000); // 1초 = 1000밀리초
console.log("작업들이 예약되었어요. 기다려주세요..."); // 바로 실행되는 안내 메시지
이 예시에서 볼 수 있듯이, 단순히 세 개의 작업을 순서대로 실행하려고 해도 코드가 벌써 계단 모양으로 복잡해져요. 각 작업이 끝난 후 다음 작업을 시작해야 하므로 콜백 안에 콜백을 넣을 수밖에 없는 구조가 되었어요. 만약 작업이 10개, 20개라면 어떻게 될까요?
🔹 두 번째 예시: 실제적인 상황에서의 콜백 지옥
두 번째 예시에서는 웹 개발에서 실제로 만날 수 있는 상황을 시뮬레이션해서 콜백 지옥을 경험해볼게요.
// 사용자 정보 가져오기 → 친구 목록 가져오기 → 메시지 보내기 순서
console.log("사용자 정보 처리를 시작해요..."); // 시작 안내 메시지
// 1단계: 사용자 정보 가져오기 (서버 요청 시뮬레이션)
function getUserInfo(userId, callback) {
setTimeout(() => {
console.log("✅ 사용자 정보를 성공적으로 가져왔어요!"); // 1단계 완료 메시지
callback({ name: "김철수", id: userId }); // 사용자 정보를 콜백으로 전달
}, 1000); // 1초 후에 실행
}
// 2단계: 친구 목록 가져오기
function getFriendsList(user, callback) {
setTimeout(() => {
console.log("✅ " + user.name + "님의 친구 목록을 가져왔어요!"); // 2단계 완료 메시지
callback(["이영희", "박민수", "최지영"]); // 친구 목록을 콜백으로 전달
}, 1000); // 1초 후에 실행
}
// 3단계: 메시지 보내기
function sendMessage(friends, message, callback) {
setTimeout(() => {
console.log("✅ " + friends.length + "명의 친구들에게 메시지를 보냈어요!"); // 3단계 완료 메시지
callback("메시지 전송 완료"); // 결과를 콜백으로 전달
}, 1000); // 1초 후에 실행
}
// 콜백 지옥 시작! 😱
getUserInfo("user123", (user) => {
console.log("사용자 정보:", user.name); // 1단계 결과 출력
getFriendsList(user, (friends) => {
console.log("친구 수:", friends.length + "명"); // 2단계 결과 출력
sendMessage(friends, "안녕하세요!", (result) => {
console.log("최종 결과:", result); // 3단계 결과 출력
console.log("🎊 모든 과정이 완료되었어요!"); // 전체 완료 메시지
// 만약 여기서 또 다른 작업을 해야 한다면...?
// 콜백 지옥이 더욱 깊어질 거예요!
});
});
});
이 예시는 실제 웹 애플리케이션에서 흔히 볼 수 있는 패턴이에요. 각 단계가 이전 단계의 결과에 의존하므로 순서대로 실행되어야 하고, 그 결과 콜백 함수들이 중첩되면서 복잡한 구조가 만들어졌어요. 실제 개발에서는 이보다 훨씬 더 복잡한 경우가 많아요.
🔹 세 번째 예시: 에러 처리까지 포함된 콜백 지옥
세 번째 예시에서는 에러 처리까지 포함된 콜백 지옥이 얼마나 복잡해지는지 확인해볼게요.
// 각 단계에서 에러가 발생할 수 있는 상황을 시뮬레이션해요
function stepOne(callback) {
setTimeout(() => {
let success = Math.random() > 0.3; // 70% 확률로 성공
if (success) {
console.log("1단계 성공!"); // 성공 메시지
callback(null, "1단계 결과"); // 성공시 null(에러 없음)과 결과 전달
} else {
console.log("❌ 1단계에서 에러 발생!"); // 에러 메시지
callback("1단계 에러", null); // 에러 발생시 에러 메시지와 null 전달
}
}, 1000); // 1초 후에 실행
}
function stepTwo(data, callback) {
setTimeout(() => {
let success = Math.random() > 0.3; // 70% 확률로 성공
if (success) {
console.log("2단계 성공!"); // 성공 메시지
callback(null, data + " + 2단계 결과"); // 성공시 이전 결과와 합쳐서 전달
} else {
console.log("❌ 2단계에서 에러 발생!"); // 에러 메시지
callback("2단계 에러", null); // 에러 발생시 에러 메시지와 null 전달
}
}, 1000); // 1초 후에 실행
}
// 에러 처리가 포함된 콜백 지옥
stepOne((error1, result1) => {
if (error1) {
console.log("최종 실패:", error1); // 1단계에서 에러가 발생한 경우
return; // 더 이상 진행하지 않고 종료
}
stepTwo(result1, (error2, result2) => {
if (error2) {
console.log("최종 실패:", error2); // 2단계에서 에러가 발생한 경우
return; // 더 이상 진행하지 않고 종료
}
// 3단계도 있다면...
setTimeout(() => {
console.log("🎉 모든 단계 성공:", result2); // 모든 단계 성공시 메시지
}, 1000); // 1초 후에 실행
});
});
에러 처리까지 포함하면 콜백 지옥이 더욱 복잡해져요. 각 단계마다 에러를 확인하고 처리해야 하므로 코드가 길어지고, 어디서 무엇이 잘못되었는지 파악하기 어려워져요.
🔄 콜백 지옥 발생하는 순서 정리하기
지금까지 살펴본 콜백 지옥이 어떻게 만들어지는지 과정을 정리해볼게요.
첫 번째 단계는 순차적 작업 필요성 인식이에요. A 작업이 끝난 후 B 작업을 해야 하고, B가 끝난 후 C를 해야 하는 상황이 생겨요. 이는 웹 개발에서 매우 흔한 상황이에요.
두 번째는 콜백 함수 중첩 시작 단계예요. 순서를 보장하기 위해 첫 번째 작업의 콜백 함수 안에 두 번째 작업을 넣고, 두 번째 작업의 콜백 함수 안에 세 번째 작업을 넣기 시작해요.
세 번째는 들여쓰기 깊어짐 단계예요. 중첩이 계속되면서 코드가 오른쪽으로 계속 밀려나고, 계단 모양의 구조가 만들어져요.
네 번째는 복잡성 엄청나게 증가 단계예요. 에러 처리, 조건 분기, 변수 관리 등이 복합되면서 코드의 복잡성이 엄청나게 증가해요.
마지막 단계는 관리 어려움이에요. 코드를 읽기 어려워지고, 수정하기 어려워지며, 버그를 찾기도 어려워져서 개발 효율성이 크게 떨어져요.
🏢 이야기로 다시 배우기: 우리 학교의 복잡한 요리 시간
지금까지 배운 내용을 하나의 이야기로 다시 정리해볼까요?
우리 학교의 요리 시간에서 선생님이 매우 특별한 레시피를 알려주었어요. "특별한 케이크"를 만드는 방법인데, 단계가 정말 많았어요.
처음에는 간단해 보였어요:
- "밀가루를 준비하고 나서..."
- "그것이 끝나면 우유를 넣고..."
- "그것도 끝나면 달걀을 깨뜨리고..."
- "그 다음에는 설탕을 넣고..."
하지만 실제로 레시피를 적어보니 마음 아픈 일이 일어났어요:
"밀가루를 준비한 후에 (
우유를 넣은 후에 (
달걀을 깨뜨린 후에 (
설탕을 넣은 후에 (
꿀을 바른 후에 (
소금을 뿌린 후에 (
버터를 발라서 (
바닐라를 넣어서 완성!
)
)
)
)
)
)
)"
레시피가 끝없는 괄호의 미로가 되어버렸어요! 어디서 시작하고 어디서 끝나는지 알 수가 없었어요. 중간에 실수라도 하면 어느 단계에서 잘못되었는지 찾기가 너무 어려웠죠.
더 큰 문제는 레시피를 바꾸려고 할 때였어요. "아, 달걀 대신 계란을 써야겠다"라고 생각했는데, 그 부분을 찾으려면 괄호를 하나씩 따라가며 어디가 달걀 단계인지 찾아야 했어요.
결국 학생들은 "이 레시피는 너무 복잡해서 요리를 할 수가 없어요!"라고 선생님께 말씀드렸어요. 그래서 선생님은 더 좋은 방법을 가르쳐주기로 했어요.
이것이 바로 콜백 지옥의 현실이에요. 처음에는 간단해 보이지만, 단계가 많아질수록 괄호와 중첩이 끝없이 복잡해져서 마치 출구 없는 미로처럼 되어버리는 거죠!
🧠 콜백 지옥의 문제점들
콜백 지옥이 왜 문제가 되는지 구체적으로 정리해볼게요.
❌ 문제점 1: 읽기 어려움
// 이런 코드를 봤을 때 한눈에 이해할 수 있나요?
getData((data) => {
processData(data, (processed) => {
saveData(processed, (saved) => {
sendNotification(saved, (sent) => {
logActivity(sent, () => {
console.log("모든 작업 완료");
});
});
});
});
});
코드가 계단 모양으로 중첩되면서 어디서 시작하고 끝나는지, 어떤 순서로 실행되는지 파악하기 매우 어려워져요. 특히 코드가 길어질수록 더욱 복잡해져요.
❌ 문제점 2: 수정과 확장의 어려움
// 중간에 새로운 단계를 추가하려면?
getData((data) => {
processData(data, (processed) => {
// 여기에 새로운 검증 단계를 추가하려면 전체 구조를 바꿔야 함
validateData(processed, (validated) => {
saveData(validated, (saved) => {
// ... 계속
});
});
});
});
중간에 새로운 단계를 추가하거나 순서를 바꾸려면 여러 곳을 동시에 수정해야 하므로 실수하기 쉽고 번거로워요.
❌ 문제점 3: 에러 처리의 복잡성
// 각 단계마다 에러 처리를 해야 함
getData((error, data) => {
if (error) {
console.log("정보 가져오기 실패");
return;
}
processData(data, (error, processed) => {
if (error) {
console.log("정보 처리 실패");
return;
}
// 에러 처리 코드가 반복되면서 복잡해짐
});
});
각 단계마다 에러 처리 코드를 반복해서 작성해야 하고, 에러가 어느 단계에서 발생했는지 추적하기 어려워져요.
✏️ 연습문제로 개념 다지기
천천히, 마치 시를 읽듯 문제를 풀어보세요. 복잡한 구조 속에서도 우리는 배움의 실마리를 찾을 수 있을 거예요.
Ex1) 다음 코드에서 콜백이 몇 번 중첩되어 있는지 세어보자
setTimeout(() => {
console.log("1단계"); // 첫 번째 콜백
setTimeout(() => {
console.log("2단계"); // 두 번째 콜백 (첫 번째 안에 중첩)
setTimeout(() => {
console.log("3단계"); // 세 번째 콜백 (두 번째 안에 중첩)
}, 1000);
}, 1000);
}, 1000);
정답: 3번 중첩되어 있어요.
이 연습을 통해 콜백 중첩을 인식하는 능력을 기를 수 있어요.
Ex2) 다음 코드가 콜백 지옥인 이유를 설명해보자
getUser((user) => {
getProfile(user, (profile) => {
getFriends(profile, (friends) => {
sendMessage(friends, () => {
console.log("완료!");
});
});
});
});
정답: 함수 안에 함수가 4번 중첩되어 있어서 코드가 계단 모양으로 복잡해졌고, 읽기도 수정하기도 어려워졌기 때문이에요.
Ex3) 콜백 지옥을 "피라미드"라고 부르는 이유를 설명해보자
정답: 코드가 오른쪽으로 계속 들여쓰기되면서 시각적으로 삼각형(피라미드) 모양을 만들기 때문이에요.
🤔 심화 문제로 실력 확인하기
기본 연습을 마쳤다면, 이제 조금 더 깊이 있는 문제들을 통해 콜백 지옥에 대한 이해를 확인해보겠어요.
Q1. 콜백 지옥이 생기는 가장 근본적인 원인은 무엇일까요?
정답: 순서대로 실행해야 하는 작업들을 콜백 함수만으로 처리하려고 할 때, 각 작업의 완료를 기다리기 위해 콜백 안에 콜백을 계속 중첩시키기 때문이에요.
해설: 각 작업이 이전 작업의 결과에 의존하므로, 콜백 함수만으로는 순서를 보장하기 위해 중첩할 수밖에 없는 구조상의 문제가 있어요.
Q2. 콜백 지옥에서 에러가 발생했을 때 어떤 문제가 생길까요?
정답: 어느 단계에서 에러가 발생했는지 파악하기 어렵고, 각 단계마다 개별적으로 에러 처리를 해야 해서 코드가 복잡해지며, 일관성 있는 에러 처리가 어려워져요.
해설: 중첩이 깊어질수록 에러의 원인을 추적하기 어려워지고, 에러 처리 코드도 여러 곳에 분산되어 관리하기 힘들어져요.
🔙 지난 시간 복습하기 (13.2.1 - 콜백 함수)
13.2.2를 계속 공부하기 전에, 지난 시간에 배운 콜백 함수 내용을 복습해볼까요?
복습 문제 1: 콜백 함수의 정의
다음 중 콜백 함수에 대한 설명으로 올바른 것은?
// A) 호출하는 함수
// B) 다른 함수에 전달되어 나중에 실행되는 함수
// C) 즉시 실행되는 함수
// D) 변수에 저장할 수 없는 함수
정답: B) 다른 함수에 전달되어 나중에 실행되는 함수
설명: 13.2.1에서 배운 콜백 함수는 다른 함수에게 "나중에 이 일을 해달라"라고 맡겨두는 함수예요. setTimeout 같은 함수에 전달해서 적절한 시점에 실행되도록 하는 거죠.
복습 문제 2: 콜백 함수 전달 방법
다음 코드에서 잘못된 부분을 찾아보세요.
function sayHello() {
console.log("안녕하세요!");
}
// A) setTimeout(sayHello, 1000)
// B) setTimeout(sayHello(), 1000)
정답: B가 잘못되었어요.
설명: 콜백 함수를 전달할 때는 함수 이름 뒤에 괄호를 붙이면 안 돼요. 괄호를 붙이면 함수가 즉시 실행되어서 그 결과가 전달되기 때문이에요. 함수 자체를 전달해야 해요.
지금까지 콜백 지옥의 모든 문제점을 자세히 알아보았어요. 이 문제들을 이해하는 것은 단순히 문제점을 아는 것을 넘어서, 앞으로 배울 Promise와 async/await 같은 더 나은 해결책의 가치를 깨닫는 데 매우 중요해요. 마치 미로에서 길을 잃어봐야 지도의 소중함을 알게 되는 것처럼, 콜백 지옥의 아픔을 이해해야 더 좋은 방법들의 필요성을 절실히 느낄 수 있게 돼요!
✅ 학습 완료 체크리스트
이번 시간에 배운 내용들을 모두 이해했는지 확인해보세요!
학습 내용 | 이해했나요? |
---|---|
콜백 지옥의 기본 개념 | ✅ |
콜백 지옥이 생기는 이유 | ✅ |
러시아 인형 비유 이해하기 | ✅ |
콜백 지옥의 문제점들 | ✅ |
실전 예제 이해하기 | ✅ |
🎯 추가 연습 문제들
조금 더 연습하고 싶은 분들을 위한 추가 문제들이에요!
추가 문제 1. 다음 콜백 지옥 코드에서 몇 번 중첩되었는지 세어보세요.
setTimeout(() => {
setTimeout(() => {
setTimeout(() => {
console.log("끝!");
}, 1000);
}, 1000);
}, 1000);
답: 3번 중첩
설명: setTimeout 안에 setTimeout이 3번 겹쳐 있어요.
추가 문제 2. 다음 코드가 콜백 지옥인 이유를 설명해보세요.
getData((data) => {
processData(data, (result) => {
saveData(result, () => {
console.log("완료!");
});
});
});
답: 함수 안에 함수가 3번 중첩되어 코드가 복잡해졌기 때문
설명: 각 함수가 콜백으로 다음 함수를 호출하면서 중첩 구조를 만들어요.
추가 문제 3. 콜백 지옥의 가장 큰 문제점 3가지를 써보세요.
답:
- 읽기 어려움
- 수정하기 어려움
- 에러 처리가 어려움
설명: 이 3가지가 콜백 지옥의 주요 문제점들이에요.
추가 문제 4. 다음 중 콜백 지옥의 특징이 아닌 것은?
A) 코드가 계단 모양으로 들여쓰기됨
B) 함수 실행 속도가 느려짐
C) 에러 처리가 복잡해짐
정답: B) 함수 실행 속도가 느려짐
해설: 콜백 지옥은 실행 속도 문제가 아니라 코드 구조와 가독성 문제입니다.
추가 문제 5. 콜백 지옥을 피하려면 어떻게 해야 할까요?
정답: 함수를 분리하거나, Promise, async/await 같은 더 좋은 방법을 사용해야 합니다.
해설: 앞으로 배울 Promise와 async/await가 콜백 지옥을 해결하는 방법입니다.
📂 마무리 정보
오늘 배운 13.2.2
내용이 여러분의 자바스크립트 지식에 잘 저장되었나요? 다음 시간에는 더 재미있는 내용으로 만나요!
기억할 점: 오늘 배운 내용을 꼭 연습해보시고, 궁금한 점이 있으면 언제든 다시 돌아와서 읽어보세요.
무료 JavaScript 학습 플랫폼에서 단계별 학습과 실시간 코드 실행을 통해
더욱 효과적이고 재미있게 학습하실 수 있습니다.
'13. 시간을 다루는 마법 (비동기 처리) > 13.2 콜백 함수와 콜백 지옥' 카테고리의 다른 글
13.2.3 복잡한 코드를 정리하는 방법 - 함수를 나누어서 깔끔하게 만들기 (0) | 2025.07.18 |
---|---|
13.2.1 콜백 함수란? - 다른 함수에게 맡기는 특별한 임무 (0) | 2025.07.18 |