Daily Notebook

콜백 함수(Callback function)

by 배부른코딩로그
나(A)는 할 일 다했어... 이제 너(B)가 일할 차례야...!! A → B 제어권 짬처리~

jQuery를 사용할 때, 콜백 함수를 지겹게 사용하게 될 겁니다.

 

그 콜백 함수를 간단히 다듬어 봅시다.

 

먼저, 콜백 함수는 명칭 그대로 함수입니다.

당연한 소리지만, 이는 this와 또 연관되어 있습니다.

 

콜백 함수로 어떤 객체의 메서드를 전달하더라도 그 메서드는 함수로서 호출된다는 뜻입니다.

 

아래의 예제에서 콜백 함수로 실행된 obj.func의 결과를 확인하면 다음과 같습니다.

var obj = {
  item: [1, 2, 3],
  func: function (v, i) {
    console.log(this, v, i)
  },
}
obj.func(1, 2);
['a', 'b', 'c'].forEach(obj.func);

/* -------------------------------- result --
{
	item:(3) [...],
	func:f func {...}
}
1 2
[object Window]
a 0
[object Window]
b 1
[object Window]
c 2
*/ 

 

또, 알아두셔야 할 것은 콜백 함수의 실행 방식과 제어권입니다.

code 호출 주체 제어권
obj.func(1, 2); 사용자 사용자
['a', 'b', 'c'].forEach(obj.func); forEach forEach

위 표가 이해되시나요..?

 

음, forEach를 setInterval로 변경해서 생각해보시죠.

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

/* -------------------------------- result --
1 (0.5초 후)
2 (1.0초 후)
3 (1.5초 후)
4 (2.0초 후)
*/ 
code 호출 주체 제어권
itvFunc(1, 2); 사용자 사용자
setInterval(itvFunc, 500); setInterval setInterval

 

그저 함수로 호출하면, 호출 주체는 사용자고 제어권도 사용자에게 그대로 있습니다.

 

하지만, 0.5초마다 setInterval이 호출 및 실행되면서 제어권도 setInterval로 넘겨주게 됩니다.

 

위 두가지 개념을 정확히 이해하는 것이 중요합니다.

 

 

그러면, 콜백 함수 내부의 this는 항상 window일까?

 

아닙니다 :)

 

이를 위해 call, apply, bind가 존재하며, 이를 통해서 this에 다른 값을 바인딩할 수 있습니다.

var obj1 = {
  name: 'Codify',
  func: function() {
    console.log(this, this.name);
  }
}
setInterval(obj1.func, 1000);
setInterval(obj1.func.bind(obj1), 1000);

/* -------------------------------- result --
Window:[object Window] (1.0초 후)

{
  name:"Codify",
  func:f func {...}
}
Codify 
*/ 

ES5부터 사용 가능한 bind 메서드를 통해 this에 다른 값을 강제 바인딩할 수 있습니다.

 

 

그렇다면, 콜백 함수는 단점이 없을까?

 

있습니다 :)

 

바로 콜백 지옥(Callback Hell)입니다.

콜백 지옥이란, 콜백 함수를 익명 함수로 전달하는 과정이 반복되어 코드의 들여쓰기 수준이 감당 불가능하게 되는 현상입니다.

 

/* example */
call1(function (value1) {
    call2(function (value2) {
        call3(function (value3) {
            call4(function (value4) {
                call5(function (value5) {
                   // Do something continue...
                });
            });
        });
    });
});

 

주로 이벤트 처리나 서버통신과 같은 비동기적인 작업에서 자주 등장하게 됩니다.

 

이를 해결하기 위해서 비동기적인 일련의 작업을 동기적으로, 혹은 동기적인 것 처럼 보이게끔 변경할 수 있습니다.

 

바로, ES6부터 사용 가능한 Promise, Generator 혹은 ES2017에서 도입된 async/await 입니다.

 

 

해당 개념은 비동기에 대한 이해가 필요하므로, 정리하고 다시 작성하겠습니다. :)

 

 

 

 

 

 

 

[출처] '코어 자바스크립트 - 핵심 개념과 동작 원리로 이해하는 자바스크립트 프로그래밍', 정재남 지음

반응형

'자바스크립트 > 코어 자바스크립트' 카테고리의 다른 글

클로저의 활용  (0) 2020.04.07
클로저(Closure)  (0) 2020.04.05
this  (0) 2020.03.28
메모리와 데이터  (0) 2020.03.21
데이터 타입의 종류  (0) 2020.03.21

블로그의 정보

배부른코딩로그

배부른코딩로그

활동하기