콜백 함수(Callback)

어니·2022년 11월 3일
0

TIL

목록 보기
2/16
post-thumbnail

4. 콜백 함수

1 . 콜백함수란?


'Call' : 부르다, 호출(실행)하다. 'back' : 뒤돌아오다, 되돌다

되돌아 호출해달라 라는 뜻! 어떤 함수X를 호출하면서 '특정 조건일 때, 함수Y를 실행해서 알려달라'


이 요철을 받은 함수X는 해당 조건이 갖춰졌는지 여부를 판단 한 후 함수Y를 직접 호출한다.

다른 함수의 인자로서 사용되는 함수
어떤 이벤트에의해 호출되어지는 함수

이처럼 콜백함수는 다른 코드(함수or메서드)에게 인자로 남겨줌으로써 그 제어권도 함께 위임하는 함수이다. 콜백함수를 위임받은 코드는 자체적인 내부 로직에 의해 이 콜백함수를 적절한 시점에 실행한다.




2 . 제어권


4-2-1 호출시점

    var count = 0;
    var timer = setInterval(function() {
        console.log(count);
        if(++count > 4) clearInterval(timer)
    },300)
var intervalID = scope.setInterval(func, delay[, param1, param2, ...])

setInterval()의 구조

scope : 스코프에는 window객체, worker의 인스턴스가 들어올 수 있다.
func은 함수이고, delay는 밀리초(ms) 단위의 숫자. 세 번째부터는 선택적인데 func함수를 실핼 때 매개변수로 전달할 인자이다.


setInterval를 실행하면 반복적으로 실행되는 내용자체를 특정할 수 있는 고유한 ID값으로 반환된다.

timer의 ID를 int형태로 반환함!


다른 예제

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

    var timer = setInterval(cbFunc, 300)
  • timer변수에는 setInterval의 ID 값이 담긴다.
  • setInterval에 전달한 첫 번째 인자인 cbFunc함수(이 함수가 곧 콜백함수이다)는 0.3초마다 자동으로 실행된다.
  • 콜백 함수의 내부에서는 count값을 출력하고, count + 1를 한 다음 값이 4보다 크면 반복 실행을 종료하라고 한다.



4-2-2 인자

예제)

    var newArr = [10,20,30].map(function(currentValue, index) {
        console.log(currentValue, index)
        return currentValue + 5;
    })

    console.log(newArr)

    // output
    // 10 0
    // 20 1
    // 30 2
    // [15,25,35]


map함수의 작동원리를 먼저 알아보자

    Array.prototype.map(callback[, thisArg])
    Callback : function(currentValue, index, array)
  • map 메서드는 첫 번째 인자로 callback함수를 받는다.
  • 생략이 가능한 두 번째 인자로 콜백 함수 내부에서 this로 인식할 대상을 특정할 수 있다.

    (thisArg를 생략할 경우에는 일반적인 함수와 마찬가지로 전역객체가 바인딩된다.)
  • 첫 번째 인자에는 배열 요소 중 현재값, 두 번째 인자에는 현재값의 인덱스, 세 번째 인자에는 map메서드의 대상이 되는 배열 자체가 담긴다.



예제 설명으로 다시 돌아가자면

  • 배열 [10,20.30]의 각 요소를 처음부터 하나씩 꺼내어 콜백함수를 실행한다.
  • 첫 번째 (인덱스 0)에 대한 콜백함수는 currentValue에 10, index는 0이 담긴 채 실행된다.
  • 위 2개의 값을 출력한 다음 15(10 + 5)를 반환한다.

이렇게 세 번째 배열까지 실행된 후 return값 ([15,25,35])이 나오게 된다.






3. 콜백함수는 함수다.


'콜백함수는 함수이다' 당연한 말이지만 의미를 좀더 생각해보자. 콜백함수로 어떤 객체의 메서드를 전달하더라도 그 메서드는 메서드가 아닌 함수로서 호출된다.

예제) 메서드를 콜백함수로 전달한 경우

    var obj = {
        vals : [1,2,3] ,
        logValues : function(v,i) {
            console.log(this, v, i)
        }
    };

obj.logValues(1,2);
    // output : {vals: [1,2,3] , logValues: f} 1 2
    
    
[4,5,6].forEach(obj.logValues)
    // forEach의 콜백함수로 전달
    // output : Window { ... } 4 0
    // output : Window { ... } 5 1
    // output : Window { ... } 6 2
  • obj객체의 logValues는 메서드로 정의되었다.

  • 151번줄은 이 메서드 이름 앞에 점이 있으니 메서드로서 호출한 것이다.
    따라서 this는 obj를 가리키고, 인자로 넘어온 1,2가 출력된다.

  • 155번줄은 forEach의 콜백함수로써 전달했다.

  • obj를 this로 하는 메서드를 그대로 전달한 것이 아니라, obj.logValues가 가리키는 함수만 전달한 것이다.

  • 이 함수는 obj와 직접적인 연관이 없어진다.

  • forEach에 의해 콜백이 함수로서 호출되고, 별도로 this를 지정하는 인자를 지정하지 않았음으로 함수 내부에서의 this는 전역객체를 바라보게 된다.


어떤 함수의 인자에 객체의 메서드를 전달하더라도 이는 결국 메서드가 아닌 함수일 뿐입니다. 이 차이를 정확히 이해하는 것이 중요!!!





콜백 함수 내부의 this에 다른 값 바인딩하기


Q. 콜백 함수 내부에서 this가 객체를 바라보게 하고 싶다면 어떤 방법이 있을까?


전통적으로 this를 다릉 변수에 담아 콜백 함수로 활용할 함수에서는 this대신 그 변수를 사용하게 되고, 이를 클로저로 만드는 방식이 많이 쓰였다.



예제1) 콜백 함수 내부의 this에 다른 값을 바인딩하는 방법(1) - 전통적인 방식

    var obj1 = {
        name : 'obj1',
        func : function() {
            var self = this;
            return function() {
                console.log(self.name)
            };
        }
    };

    var callback = obj1.func();
    setTimeout(callback, 1000);
  • 198번 줄에서 obj1.func를 호출하면 앞서 선언한 내부함수가 반환되어 callback변수에 담긴다.

  • 199번 줄에서 이 callback을 setTimeout함수에 인자로 전달하면 1초(1000ms) 뒤 callback이 실행되면서 'obj1'을 출력한다.



    하지만 이 방식은 실제로 this를 사용하지도 않고 번거롭기도 하다. 다음 게시글에서 콜백함수 내부에서 this를 좀더 살펴보자!

profile
개린이

0개의 댓글