본문 바로가기

프로그래밍/자바스크립트

자바스크립트 콜백 함수 (javascript Callback Function)



콜백함수란?

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라는 것이 있습니다.

이상으로 콜백함수에 대해 알아봤습니다.