JavaScript: 도대체 콜백이 뭔데?

Ryu
6 min readDec 13, 2018

--

이 문서는 Brandon MorelliJavaScript: What the heck is a Callback? 을 번역한 것입니다. 잘못된 부분이 있는 경우 알려주시면 감사하겠습니다.

단 6분 만에 쉬운 예제로 콜백의 기본을 이해하고 배우자.

콜백이란 무엇이냐?

간단히: 콜백은 다른 함수가 실행을 끝낸 뒤 실행되는 — call back 되는 함수를 말한다.

조금 자세히: 자바스크립트에서 함수는 object이다. 이 때문에 함수는 다른 함수의 인자로 쓰일 수도, 어떤 함수에 의해 리턴될 수도 있다. 이러한 함수를 고차 함수 higher-order functions 라 부르고 인자로 넘겨지는 함수를 콜백 함수 callback function 라고 부른다.

^장황한 설명이다. 예제를 보며 파헤쳐보자!

왜 콜백함수가 필요한가?

아주 중요한 이유 — 자바스크립트는 이벤트 기반 언어이기 때문이다. 자바스크립트는 다음 명령어를 실행하기 전 이전 명령어의 응답을 기다리기보단, 다른 이벤트들을 기다리며 계속 명령을 수행한다. 간단한 예제를 보자.

function first(){
console.log(1);
}
function second(){
console.log(2);
}
first();
second();

당신이 예상하듯이 first 함수가 먼저 실행되고 second 함수가 그다음에 실행될 것이다.

// 1
// 2

여기까진 오케이.

그런데 만약 first 함수가 즉시 완료될 수 없는 코드를 포함한다면 어떨까? 예를 들어, 요청 request을 보낸 후 응답 response을 기다려야하는 API라면? 이를 구현하기 위해 setTimeout 함수를 써보자. setTimeout 함수는 지정된 시간이 지난 후에 함수를 call한다. 우리는 API 요청을 흉내 내기 위해서 함수 콜을 500ms만큼 지연시킬 것이다. 새로운 코드는 다음과 같다.

function first(){
// Simulate a code delay
setTimeout( function(){
console.log(1);
}, 500 );
}
function second(){
console.log(2);
}
first();

지금은 setTimeout 함수가 어떻게 동작하는지 이해할 필요는 없다. 중요한 건 우리가 console.log(1);를 500ms 딜레이 시켰다는 것이다. 이제 우리 함수를 실행하면 어떻게 될까?

first();
second();
// 2
// 1

비록 우리가 first()함수를 먼저 콜했더라도 그 결과는second()함수의 결과 이후에 찍힌다.

이는 자바스크립트가 우리가 원하는 순서대로 함수를 수행하지 않았다는 게 아니다. 이는 자바스크립트가 first()함수로부터의 응답을 기다린 후에야 second() 함수를 수행하는 게 아니라는 뜻이다.

콜백 만들기

설명은 이제 그만하고 직접 콜백 함수를 만들어 보자!

먼저, 크롬 개발자도구를 열고 (Windows: Ctrl + Shift + J)(Mac: Cmd + Option + J) 당신의 콘솔에 다음과 같은 함수 선언을 해보라.

function doHomework(subject) {
alert(`Starting my ${subject} homework.`);
}

위와 같이 우리는 doHomework 라는 함수를 만들었다. 이 함수는 우리가 공부할 과목을 변수로 받는다. 당신의 콘솔에 다음과 같이 입력해 함수를 불러보자.

doHomework('math');// Alerts: Starting my math homework.

doHomework() 함수의 두 번째 인자로 callback을 넘겨줌으로써 콜백 함수를 추가해보자. 이제 우리는 doHomework() 함수를 호출할 때 두 번째 인자 자리에서 콜백 함수를 정의할 수 있다.

function doHomework(subject, callback) {
alert(`Starting my ${subject} homework.`);
callback();
}

doHomework('math', function() {
alert('Finished my homework');
}
);

당신도 보겠지만, 위의 코드를 입력하면 당신은 2개의 alert를 연달아서 받을 것이다: 'starting homework’ 메세지와, 그 다음에 ‘finished homework’ 메세지를 말이다.

사실 콜백 함수를 꼭 함수 호출 시에 정의할 필요는 없다. 다음과 같이 콜백함수는 스크립트의 어느 부분에서라도 정의될 수 있다:

function doHomework(subject, callback) {
alert(`Starting my ${subject} homework.`);
callback();
}
function alertFinished(){
alert('Finished my homework');
}
doHomework('math', alertFinished);

위 예제의 결과는 바로 전 예제와 완전 같을 것이다. 하지만 코드 구성이 약간 다르다. 당신이 알 수 있듯이, 우리는 doHomework() 함수를 호출할 때 alertFinished 함수의 정의를 인자로 넘겨준다!

실제 사용 예제

지난 주에 나는 어떻게 38줄의 코드로 트위터 봇을 만드는가(Build a simple Twitter Bot with Node.js in just 38 lines of code)에 대한 블로그를 썼다. 그 블로그의 코드들이 동작하는 이유는 순전히 Twitters API 덕분이다. 당신이 어떤 API에 요청을 보내면, 당신은 API의 응답에 대응하기 전에 일단 그 응답을 기다려야한다. 이는 실제로 콜백 함수가 어떻게 쓰이는지에 대한 아주 좋은 예제이다! 여기 API요 청을 보자.

T.get('search/tweets', params, function(err, data, response) {
if(!err){
// This is where the magic will happen
} else {
console.log(err);
}
})
  • T.get 는 우리가 Twitter에 GET 요청을 보낸다는 뜻이다.
  • 이 요청에는 세 개의 인자가 있다: 'search/tweets’ 는 요청의 경로, params 는 우리의 검색 인자들, 그리고 어떤 익명함수 — 우리의 콜백 이다.

콜백은 우리가 이 코드의 다음 로직으로 넘어가기 전에 API의 응답을 기다려야 하기 때문에 중요하다! 우리는 현재 API 요청이 성공할지 실패할지 모르기 때문에 일단 우리의 파라미터들을 던져놓고 기다린다. 일단 Twitter가 응답하기만 하면 우리의 콜백 함수가 실행된다. Twitter는 err (error) object나 response object를 보낼 것이고 우리는 콜백 함수 내에서 if() 문을 사용함으로써 우리의 요청이 성공했는지 아닌지를 판단할 수 있다. 그 후에 새로운 데이터를 처리하면 된다.

해냈다!

잘했다! 당신은 이제 콜백이 무엇이고 어떻게 동작하는지 (이상적으로는) 이해했다. 사실 이는 콜백 함수라는 빙산의 일각일 뿐 아직도 배울 것이 많다. 나는 매주 몇 개의 블로그와 튜토리얼을 작성하므로 매주 한 번 이메일을 받고 싶다면 여기에 당신의 이메일을 적길 바란다.

--

--