어떤 함수 a의 parameter로 들어가서 a 함수 내부에서 호출되는 함수이다.
다른 함수에 parameter로 전달되는 함수
Array.prototype.map(), Array.prototype.forEach()에 인자로 들어가는 함수setTimeOut(), addEventListener()에 인자로 들어가는 함수비동기 처리를 할 때 어떤 처리를 하고 => 또 그걸 받아서 어떤 처리를 하고 => ... 이렇게 연쇄적으로 콜백 함수를 쓰면 발생한다
가독성이 떨어지고 유지보수가 어려운 코드 구조이다
챗 선생님이 알려준 예시
// 비동기적으로 동작하는 함수 1
function asyncFunction1(callback) {
setTimeout(function () {
console.log("Async Function 1");
callback();
}, 1000);
}
// 비동기적으로 동작하는 함수 2
function asyncFunction2(callback) {
setTimeout(function () {
console.log("Async Function 2");
callback();
}, 1000);
}
// 비동기적으로 동작하는 함수 3
function asyncFunction3(callback) {
setTimeout(function () {
console.log("Async Function 3");
callback();
}, 1000);
}
// 콜백 지옥
asyncFunction1(function () {
asyncFunction2(function () {
asyncFunction3(function () {
console.log("작업 완료");
});
});
});
Promise나 async/await을 쓰면 해결이 가능하다.then() 으로 콜백 함수를 chaining하기 때문에 가독성, 유지보수성이 좋게 콜백 함수들을 작성할 수 있다.then()의 두번째 인자에 에러 발생 시 호출할 콜백 함수를 주거나, .catch()를 사용해 에러를 처리할 수 있다try...catch 블록을 사용해 간편하게 예외 처리를 할 수 있다function asyncFunction(callback) {
setTimeout(function () {
const error = Math.random() > 0.5 ? new Error("에러 발생!") : null;
if (error) {
callback(error, null);
} else {
callback(null, "작업 완료!");
}
}, 1000);
}
asyncFunction((error, result) => {
if (error) {
console.error("에러 발생:", error);
} else {
console.log("결과:", result);
}
});
function asyncFunction() {
// resolve: 프로미스가 이행됐을 때(정상적일 때) 호출할 함수
// reject: 프로미스가 거절되었을 때(비정상적일 때) 호출할 함수
return new Promise((resolve, reject) => {
setTimeout(function () {
const error = Math.random() > 0.5 ? new Error("에러 발생!") : null;
if (error) {
reject(error);
} else {
resolve("작업 완료!");
}
}, 1000);
});
}
async function executeAsyncFunction() {
try {
const result = await asyncFunction();
console.log("결과:", result);
} catch (error) {
console.error("에러 발생:", error);
}
}
executeAsyncFunction();