Core Javascript - 콜백함수

김규빈·2021년 2월 19일
0
post-thumbnail

이 글은 Core Javascript를 읽고 내용을 정리하였습니다. 2회독 하였지만 잘못된 내용의 지적을 감사히 받겠습니다.

콜백함수에 대해 코어적으로 접근해 보자!

콜백함수란?

콜백 함수는 다른 코드의 인자로 넘겨주는 함수 이다. 콜백 함수를 넘겨받은 코드는 이 콜백 함수를 필요에 따라 적절한 시점에 실행한다.
콜백함수를 이해하는 적절한 예시를 들어보겠다.
A와 B는 다음 날 아침 8시에 만나기로 하고 잠을 잡니다. 약속 장소에 가려면 늦어도 6시에는 일어나야 합니다. A는 불안한 마음에 수시로 깨어 시계를 확인하고 계속 잠을 설치다가 결국 5시 즈음 포기하고 일어나고야 맙니다. 반면 스마트한 B는 알람시계를 세팅합니다. 시계가 정한 시각에 울리지 않을 염려는 업속 평소 알람소리에 쉽게 눈을 뜨곤 했던지라 안심하고 꿀잠을 잡니다. 6시가 되자 시계의 알람소리를 듣고 상쾌하게 일어납니다.

이 예제에서 A는 수시로 시간을 구하는 함수를 직접 호출했다. 반면 B는 시계의 알람을 설정하는 함수를 호출했고, 해당 함수는 호출 당시에는 아무것도 하지 않았다가 B가 정의한 시간이 됐을 때 비로소 알람을 울리는 결과를 반환한다. 차이점이 보이시나요? 이 예제에서 올바른 함수를 구현한건 B다. A의 경우 시계 함수의 제어권은 A에게 있고, 시계는 그저 요청받은 내용을 이행할 뿐이다. 반면 B는 시계 함수에게 요청을 하면서 알람을 우릴는 명령에 대한 제어권을 시계에게 넘겨준 것. 이처럼 콜백 함수는 제어권과 관련이 깊다

Callback은 '부르다', '호출하다'는 의미인 call과 '뒤돌아오다','되돌다' 라는 의미인 back의 합성어로 합쳐보면 되돌아 호출해달라는 명령이다.

간단한 콜백함수의 코드를 보자.

var count = 0;
var timer = setInterval(function(){
  console.log(count);
  if(++count >4) clearInterval(timer)
}, 300)

먼저 count 변수를 선언하고 0을 할당했다. 다음으로 timer 변수를 선언하고 여기에 setInterval을 실행한 결과를 할당했다. setInterval을 호출할 때 두개의 매개변수를 전달했는데, 그중 첫 번째는 익ㅂ명 함수이고 두 번째는 300이라는 숫자이다.

setInterval의 구조를 살펴보면

var intervalID = scope.setInterval(func, delay,[, param1, param2, ...])
우선 scope에는 window 객체 또는 Worker의 인스턴스가 들어올 수 있다. 두 객체 모두 setInterval 메서드를 제공하기 때문인데, 일반적인 브라우저 환경에서는 window를 생략해서 함수처럼 사용 가능하다. 매개변수로는 func, delay값이 필수적으로 전달해야하며, 세 번째 매개변수부터는 선택적이다. func는 함수이고, delay는 밀리초 단위의 숫자이며, 나머지 는 func 함수를 실행할 때 매개변수로 전달할 인자이다. func에 넘겨준 함수는 매(delay)마다 실행되며, 그 결과 어떠한 값도 리턴하지 않습니다.

콜백에서의 this

콜백함수도 함수이기 때문에 기본적으로는 this가 전역객체를 참조하지만, 제어권을 넘겨받을 코드에서 콜백 함수에 별도로 this가 될 대상을 지정한 경우에는 그 대상을 참조하게 된다.
콜백함수는 함수이기 때문에 콜백함수로 어떤 객체의 메서드를 전달하더라도 그 메서드는 메서드가 아닌 함수로서 호출된다. 즉 콜백에서의 this는 별도의 this를 바인딩 하지 않으면 전역객체를 바라보게 될 것. 또 콜백함수는 제어권을 갖고있는 함수의 this를 따르게 된다.

콜백지옥을 해결하는 방법

예시 코드

setTimeout(function(name) {
  var 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.콜백함수를 모두 기명함수로 전환


var coffeeList = '';

var addEspresso = function(name){
	coffeeList = name;
  	console.log(coffeeList);
  	setTimeout(addAmericano, 500, '아메리카노)
}
var addAmericano = function(name){
    coffeeList += ", " + name;
  	console.log(coffeeList);
  	setTimeout(addMocha, 500, '카페모카)
}
var addMocha = function(name){
    coffeeList += ", " + name;
  	console.log(coffeeList);
  	setTimeout(addLatte, 500, '카페라떼)
}
var addLatte = function(name){
    coffeeList += ", " + name;
  	console.log(coffeeList);
}
      
setTimeout(addEspresso, 500, '에스프레소')
               
  1. promise 사용
var addCoffee =function(name) {
	return function(prevName) {
    	return new Promise(function(resolve){
        	setTimeout(function (){
              var newName = prevName ? (prevName + ' , ' + name) : name
              console.log(newName)
              resolve(newName)
              ) 
        }, 500)
    }
}
addCoffee('에스프레소')()
      .then(addCoffee('아메리카노'))
      .then(addCoffee('카페모카'))
      .then(addCoffee('카페라떼'))
  1. Async/ await

var addCoffee =function(name) {
    	return new Promise(function(resolve){
        	setTimeout(function (){
              resolve(newName)
        }, 500)
    });
};
var coffeeMaker = async function(){
	var coffeeList = '';
  	var _addCoffee = async function(name){
    	var coffeeList += (coffeeList ? " , " : "") + await addCoffee(name)
    }
  await _addCoffee("에스프레소");
 	 console.log(coffeeList)
  await _addCoffee("아메리카노");
 	 console.log(coffeeList)
  await _addCoffee("카페모카");
 	 console.log(coffeeList)
  await _addCoffee("카페라떼");
 	 console.log(coffeeList)
};
coffeeMaker();

콜백함수에 대해 정리를 해보자면,

콜백 함수는 다른 코드에 인자로 넘겨줌으로써 그 제어권도 함꼐 위임한 함수입니다. 제어권을 넘겨받은 코드는 다음과 같은 제어권을 가집니다. 1) 콜백 함수를 호출하는 시점을 스스로 판단하여 실행합니다. 2) 골백 함수를 호출할 때 인자로 넘겨줄 값들 및 그 순서가 정해져 있습니다. 이 순서를 따르지 않고 코드를 작성하면 엉뚱한 결과를 얻게 됩니다. 3) 콜백 함수의 this가 무엇을 바라보도록 할지가 정해져 있는 경우도 있습니다. 정하지 않은 경우에는 전역객체를 바라봅니다. 사용자가 임의로 this를 바꾸고 싶을 경우 bind 메서드를 활용하면 됩니다.

profile
FrontEnd Developer

0개의 댓글