본문으로 건너뛰기

콜백함수

· 약 4분
준열
프론트엔드 개발자

코어 자바스크립트 스터디 7주차 내용을 정리했습니다. 이번 주제는 콜백 함수입니다.

🎯 콜백 함수란?

콜백 함수는 다른 함수에게 실행 권한을 맡기는 함수입니다. 쉽게 말해, "이 함수를 나중에 적절한 타이밍에 실행해줘!"라고 다른 함수에게 부탁하는 것과 같습니다.

기본 개념

// 콜백 함수의 기본 개념
function 주문받기(메뉴, 완료시실행할함수) {
console.log(`${메뉴} 준비 중...`);
setTimeout(() => {
console.log(`${메뉴} 완성!`);
완료시실행할함수(); // 콜백 함수 실행
}, 2000);
}

주문받기("아메리카노", function () {
console.log("감사합니다!");
});

⏰ setInterval 예제

let count = 0;
function 숫자세기() {
console.log(count);
if (++count > 4) {
clearInterval(timer);
}
}

// setInterval이 언제 실행할지 결정
const timer = setInterval(숫자세기, 300);
// 출력: 0, 1, 2, 3, 4 (0.3초 간격)

핵심: setInterval숫자세기 함수를 언제 실행할지 완전히 통제합니다.

🗺️ map 메서드와 매개변수 순서

// map 메서드 예제
const 원본배열 = [10, 20, 30];
const 결과1 = 원본배열.map(function (, 인덱스, 전체배열) {
console.log(`값: ${}, 인덱스: ${인덱스}`);
return+ 5;
});
console.log(결과1); // [15, 25, 35]

// 매개변수 순서를 바꾸면?
const 결과2 = 원본배열.map(function (인덱스라고생각한것, 값이라고생각한것) {
return 값이라고생각한것 + 5; // 실제로는 인덱스 + 5
});
console.log(결과2); // [5, 6, 7] (인덱스 0,1,2 + 5)

주의사항: 매개변수 이름은 중요하지 않습니다. 순서가 중요해요!

🎯 this 바인딩

콜백에서의 this 변화

const 객체 = {
데이터: [1, 2, 3],
출력메서드: function (, 인덱스) {
console.log("this:", this, "값:",, "인덱스:", 인덱스);
},
};

// 메서드로 호출 - this는 객체를 가리킴
객체.출력메서드(1, 2);
// this: {데이터: Array(3), 출력메서드: ƒ} 값: 1 인덱스: 2

// 콜백으로 전달 - this는 전역 객체를 가리킴
[4, 5, 6].forEach(객체.출력메서드);
// this: Window 값: 4 인덱스: 0
// this: Window 값: 5 인덱스: 1
// this: Window 값: 6 인덱스: 2

교훈: 콜백으로 전달되는 순간, 원래 객체와의 연결이 끊어집니다.

😱 콜백 지옥 (Callback Hell)

문제가 되는 코드

setTimeout(
function (name) {
let coffeeList = name;
console.log(coffeeList);
setTimeout(
function (name) {
coffeeList += ", " + name;
console.log(coffeeList);
setTimeout(
function (name) {
coffeeList += ", " + name;
console.log(coffeeList);
setTimeout(
function (name) {
coffeeList += ", " + name;
console.log(coffeeList);
},
500,
"카페라떼"
);
},
500,
"카페모카"
);
},
500,
"아메리카노"
);
},
500,
"에스프레소"
);

이 코드의 문제점:

  • 가독성이 매우 떨어짐
  • 디버깅이 어려움
  • 코드 수정이 복잡함

🛠️ 콜백 지옥 해결 방법

1. 함수 분리

let coffeeList = "";

function 에스프레소추가(name) {
coffeeList = name;
console.log(coffeeList);
setTimeout(아메리카노추가, 500, "아메리카노");
}

function 아메리카노추가(name) {
coffeeList += ", " + name;
console.log(coffeeList);
setTimeout(모카추가, 500, "카페모카");
}

function 모카추가(name) {
coffeeList += ", " + name;
console.log(coffeeList);
setTimeout(라떼추가, 500, "카페라떼");
}

function 라떼추가(name) {
coffeeList += ", " + name;
console.log(coffeeList);
}

setTimeout(에스프레소추가, 500, "에스프레소");

2. Promise 체이닝

function 커피추가(name) {
return function (prevName) {
return new Promise((resolve) => {
setTimeout(() => {
const newName = prevName ? `${prevName}, ${name}` : name;
console.log(newName);
resolve(newName);
}, 500);
});
};
}

커피추가("에스프레소")()
.then(커피추가("아메리카노"))
.then(커피추가("카페모카"))
.then(커피추가("카페라떼"));

핵심 포인트: 커피추가는 고차함수(함수를 반환하는 함수)이고, 각 단계에서 Promise를 반환해서 체이닝이 가능합니다.

3. Generator

function 커피준비(prevName, name) {
setTimeout(() => {
const newName = prevName ? `${prevName}, ${name}` : name;
console.log(newName);
커피메이커.next(newName); // 다음 단계로 진행
}, 500);
}

function* 커피제조과정() {
const 에스프레소 = yield 커피준비("", "에스프레소");
const 아메리카노 = yield 커피준비(에스프레소, "아메리카노");
const 모카 = yield 커피준비(아메리카노, "카페모카");
const 라떼 = yield 커피준비(모카, "카페라떼");
return "주문 완료!";
}

const 커피메이커 = 커피제조과정();
커피메이커.next(); // 제조 과정 시작

핵심 포인트: yield로 함수를 멈추고, next()로 다시 시작하는 특별한 함수입니다.

4. async/await (추천!)

function 커피만들기(name) {
return new Promise((resolve) => {
setTimeout(() => resolve(name), 500);
});
}

async function 커피주문() {
let 주문목록 = "";

const 항목추가 = async (name) => {
const 커피 = await 커피만들기(name);
주문목록 += (주문목록 ? ", " : "") + 커피;
console.log(주문목록);
};

await 항목추가("에스프레소");
await 항목추가("아메리카노");
await 항목추가("카페모카");
await 항목추가("카페라떼");
}

커피주문();

핵심 포인트: 비동기 코드를 동기 코드처럼 위에서 아래로 읽을 수 있게 만드는 마법 같은 문법입니다!

📝 정리

콜백 함수란?

다른 함수에게 "나중에 실행해줘"라고 맡기는 함수

콜백 함수의 특징:

  • 다른 함수의 매개변수로 전달됨
  • 실행 시점은 호출하는 함수가 결정
  • this 바인딩이 예상과 다를 수 있음

콜백 지옥 해결 방법:

  1. 함수를 분리해서 가독성 향상
  2. Promise로 체인 구조 만들기
  3. Generator로 실행 흐름 제어하기
  4. async/await로 동기 코드처럼 작성하기 (추천!)

💡 실무 팁

콜백 함수를 사용할 때는 항상 "누가 언제 이 함수를 호출하는가?"를 생각해보세요. 그러면 예상치 못한 동작을 피할 수 있습니다!


스터디: 코어 자바스크립트 7주차