Callback 함수에 대해 정확하게 이해를 해보자.
콜백 함수(callback function)는 다른 함수에게 인수로 전달되어 어떤 이벤트나 조건이 발생했을때 실행되는 함수를 말한다.
즉, 콜백 함수는 다른 함수의 인자(parameter)로서 전달되어 나중에 호출되는 함수다. 일반적으로 비동기적인 작업이나 이벤트 처리, 타이머 함수 등에서 사용된다.
자바스크립트에서 함수는 객체이기 때문에 다른 함수의 인자로서 객체를 전달할 수 있다. 함수의 인자로서 다른 함수에 전달하고 감싼 함수의 내부에서 그 함수를 호출하는 방식이다.
function example(callback) {
callback();
}
위 코드에서 callback은 함수다. 외부에서 함수를 인자로 넘겨받아 내부에서 호출하는 것이다.
자바스크립트는 코드를 위에서 아래로 순차적으로 실행한다. 그러나, 코드가 다른 행위가 일어난 뒤에 실행되는 경우도 있고 순차적으로 실행되지 않을 때도 있다. 이런 것을 비동기 프로그래밍이라 한다.
비동기 프로그래밍에서 주로 사용되는 비동기 함수의 경우 순차적으로 실행되는 것이 아닌 비동기적으로 작업을 처리하기 때문에 비동기 작업이 끝난 후 어떠한 작업을 진행할 때 콜백 함수를 사용한다.
// 예시 1
setTimeout(function() {
console.log("비동기 작업 완료");
}, 3000);
setTimeout(() => {
console.log("비동기 작업 완료");
}, 3000);
// 예시 2
const message = function() {
console.log("비동기 작업 완료");
}
setTimeout(message, 3000);
위 코드에서 setTimeout
함수는 자바스크립트에 내장된 비동기 함수다. 첫 번째 인자로 함수를 받고 두 번째 인자로 시간(ms)을 받는다. 위 코드에서는 3초 이후에 첫 번째 인자로 받은 함수를 호출한다. 여기서 사용되는 message
라는 함수가 콜백 함수다.
예시 2에서는 외부에서 함수를 정의하고 콜백 함수로 넘겨주지만, 예시 1처럼 비동기 함수 자체에 콜백 함수를 정의하는 방법도 있는데 이것을 익명 함수라고 한다.
익명 함수는 함수 이름이 없고, 바로 함수 표현식으로 정의된다. 함수의 이름이 없기 때문에 재사용이 필요 없는 경우 익명 함수를 사용할 수 있다. 하지만 함수를 여러 곳에서 재사용할 때에는 기명 함수(이름이 있는 함수)를 사용하면 된다.
화살표 함수도 익명 함수로서 사용이 가능하다.
자바스크립트에서 특정 이벤트를 처리하기 위해 html 태그에 함수를 넘겨주는데 이것 또한 콜백 함수다
특정 액션 이후에 함수를 호출하는 방식으로 아래와 같이 사용할 수 있다.
document.getElementById("Button").addEventListener("click", function() {
console.log("click");
});
const onClick = () => { // addEventListener 함수에 인자로 넘겨준다. 즉, 콜백 함수라는 뜻
console.log("click");
}
document.getElementById("Button").addEventListener("click", onClick);
비동기 함수에서 사용한 콜백 함수와 동일하게 그냥 익명 함수나 기명 함수로 넘겨주면 된다. 해당 버튼이 클릭되었을때 인자로 넘겨준 함수가 호출된다.
Promise도 자바스크립트의 대표적인 비동기 함수인데, 위에서 설명한 비동기 함수에서의 콜백 함수 사용법과 다르지 않다.
const resolve = () => {
// Promise가 반환하는 resolve에 대한 처리
};
function fetchData() {
return new Promise((resolve) => {
setTimeout(() => {
console.log('Data fetched');
resolve();
}, 1000);
});
}
function main() {
console.log('Start');
fetchData().then(() => {
console.log('Promise resolved');
});
console.log('End');
}
main();
위 코드는 자바스크립트를 처음 배우고 있다면 조금 이해하기 힘들 수 있는데, 위 코드를 이해하고 콘솔에 출력되는 순서를 스스로 안다면 비동기 함수와 콜백에 대해서 이해하고 있는 것이라 볼 수 있다.
위의 main
함수가 호출되면 아래와 같이 콘솔에 출력된다.
Start
End
Data Fetched
Promise resolved
먼저 main
함수의 시작에서 "Start"가 콘솔에 출력된다.
이후 fetchData
함수가 호출되는데, 이 함수는 비동기 함수이기 때문에 함수가 끝나는 것을 기다리지 않고 바로 다음 코드로 넘어간다.
"End"가 콘솔에 출력된다.
fetchData
함수의 1초가 지나면서 내부의 "Data fetched"가 콘솔에 출력된다.
직후에 resolve
함수가 호출되는데 어떠한 처리를 해주지 않았기 때문에 넘어간다.
fetchData
함수의 처리가 끝난 후 then
을 사용한 콜백 함수가 호출되면서 "Promise resolved"가 콘솔에 출력된다.
콜백 함수는 크게 어려운 개념이 아니기 때문에 다른 글들을 보고 이해해도 좋다.
글을 보는 것만으로 이해가 잘 안된다면 직접 코드를 스스로 작성하고 결과를 보는 것이 제일 좋다고 생각한다.
콜백 함수를 이해했다면 콜백 지옥(callback hell)에 대해서도 알아보면 좋다.