콜백함수란?
javascript에서 콜백 함수는 너무나 중요한 개념입니다.
node.js로 서버를 운영할 때 반드시 필요한 개념이기도 합니다.
웹 개발을 해보셨으면 jquery를 한 번 쯤은 사용해보거나 보셨을 것이라 생각이 됩니다.
jquery의 코드는 콜백함수를 많이 사용하고 있기 때문에 알게 모르게 콜백함수를 사용하고 있었습니다.
콜백 함수란 어떤 이벤트가 발생한 후 수행될 함수를 의미합니다.
javascript에서 함수는 1급 객체이므로 인자로 함수를 전달할 수 있습니다.
$(".submitBtn").click(function(){
alert("제출버튼을 클릭했습니다!");
});
위의 코드는 submitBtn 클래스를 가진 요소를 클릭했을 때 콜백 함수가 실행되는 jquery 코드입니다. 즉, 비동기 이벤트인 click 이벤트에 대한 이벤트 리스너로 콜백 함수가 작성되었습니다. 이 콜백 함수는 naming을 할 필요가 없는 익명함수 입니다. 대부분의 콜백 함수는 이렇게 익명함수로써 작성됩니다.
이제부터 콜백함수에 대해 자세히 알아보도록 하겠습니다.
콜백함수는 클로저입니다.
비동기 프로그래밍을 할 때 어떤 함수의 수행 중 특정 시점에 콜백함수가 수행될 것입니다. 이 콜백함수는 자신이 포함된 함수의 환경에 접근이 가능합니다. 클로저는 함수와 함수가 선언될 때의 환경을 기억하고 있다고 했습니다.
즉, 콜백함수도 클로저입니다.
function callback(cb){
cb();
}
function add(x, y){
let sum = x + y;
callback( function(){
console.log(sum);
})
}
add(3,5);
add함수 내부에 있는 callback 함수의 인자인 익명함수가 콜백함수 입니다.
add함수는 3과 5를 인자로 받아 더한 값을 sum에 할당하고, sum변수를 콜백함수로 전달합니다.
콜백함수는 클로저이기 때문에 오류를 발생하지 않고 sum 변수를 참조할 수 있습니다.
this 객체
콜백함수를 사용할 때는 this객체에 유의해야 합니다.
var obj = {
name: "kor",
email: "abcd123",
setEmail : function(email){
this.email = email;
}
}
function callback(email, cb){
cb(email);
}
callback("aaaaaaaaa.com", obj.setEmail);
console.log(obj.email);
console.log(window.email);
obj.setEmail 프로퍼티는 email을 인자로 받아 obj의 email 프로퍼티 값을 바꾸는 함수입니다.
setEmail 함수에서는 obj 객체를 참조할 목적으로 this.email = email로 작성했습니다.
과연 email 프로퍼티 값이 바뀌었을까요?
callback()함수를 호출하고 두 번째 인자(cb() 함수)에 obj.setEmail을 함수를 전달했습니다.
즉 setEmail 함수가 실행될 때 this는 전역 객체인 window가 됩니다.
따라서 첫 번째 출력 결과는 abcd123이며, 두 번째 출력 결과는 aaaaaaaaa.com가 됩니다.
이와 같은 문제를 해결하기 위해서는 call, apply 메서드를 사용하여 this객체를 명확히 하는 방법이 있습니다.
var obj = {
name: "kor",
email: "abcd123",
setEmail : function(email){
this.email = email;
}
}
function callback(email, cb){
cb.call(obj, email);
}
callback("aaaaaaaaa.com", obj.setEmail);
console.log(obj.email);
console.log(window.email);
callback 함수에서 콜백 함수(cb)를 호출할 때 call함수를 사용하여 this객체를 명확히 전달했습니다.
따라서 첫 번째 출력 결과는 aaaaaaaaa.com이 되고, 두 번째 출력 결과는 undefined가 됩니다.
이와 같이 콜백함수를 작성할 때는 this에 주의하셔야 합니다 !
콜백지옥
콜백함수를 남용하면 콜백지옥에 빠질 수 있습니다.
function add(x, callback){
let sum = x + x;
console.log(sum);
callback(sum);
}
add(3, function(result){
add(result, function(result2){
add(result2, function(result3){
add(result3, function(result4){
console.log("에너지 파")
})
})
})
})
위의 코드는 콜백함수가 단순히 add함수를 호출하기 때문에 코드가 어려워 보이지 않을 수 있으나
실제 애플리케이션을 개발하면 이보다 훨씬 길것입니다.
코드가 얼마나 복잡해질지 ................... 코드 분석하는데만 시간이 오래걸릴 것입니다.
콜백지옥을 해결할 수 있는 방법으로 promise라는 것이 있습니다.
이상으로 콜백함수에 대해 알아봤습니다.