이번 포스팅에서는 콜백(callback)의 개념에 대해 알아보고자 한다.
콜백에 대해 설명하기에 앞서 함수를 정의하고 호출하는 등의 과정들이 어떤식으로 진행되는지에 대해 알고 넘어가야할 필요가 있다.
< 목차 >
- 함수 정의 & 호출
- 콜백(callback)
< 함수 정의 & 호출 >
JavaScript에서 함수를 정의하고 호출하는 과정들을 세분화해서 작성해 본다면 다음과 같다.
▶ aa 함수 정의하기.
function aa() {
// 코드 블록
}
▶ aa 함수 호출하기.
aa()
▶ aa 함수에 매개변수 num1과 num2를 만들기.
( 인자값을 받아줄 변수명으로 함수를 정의할 때 작성한다. )
function aa (num1, num2) {
// 코드 블록
}
▶ aa 함수에서 num1과 num2를 더한 값을 리턴(return)하기.
function aa (num1, num2) {
return num1 + num2
}
▶ aa 함수에 인자값 1과 2를 넣기.
aa(1, 2)
위에 나타나있는 과정들이 우리가 JavaScript에서 함수를 정의하고 호출해서 사용하는 방식들이다. 이렇게 정의한 aa 함수를 console.log( ) 를 사용해서 출력해보면 어떤값이 출력되게 될까?
console.log(aa)
콘솔창을 살펴보면 위와 같은 결과물이 출력된 것을 확인할 수 있을 것이다. 함수명 aa를 console.log( )를 이용해 출력한 결과 aa 함수를 구성하고 있는 코드들이 출력되는 것을 알 수 있다.
이제 조금 더 나아가 객체 안에 함수를 집어넣어 메소드를 생성해 보도록 하자.
▶ obj 라는 객체를 만들어서 sum이라는 key값에 aa 함수를 집어넣기.
function aa (num1, num2) {
return num1 + num2
}
let obj = {
sum: aa // 실행은 하지 않고 함수를 정의할 때 작성했던 코드만 들어간 형태
}
console.log( ) 를 사용하여 obj.sum(1, 2)와 obj.sum을 출력해보면 다음과 같다.
console.log(obj.sum(1,2)) // output : 3
console.log(obj.sum)
console.log(obj.sum(1,2))의 결과값으로는 3이 출력되었고 console.log(obj.sum)의 결과값으로는 함수 코드 블록이 출력된 것을 확인할 수 있다. 이 부분에서 분명히 집고 넘어가야 하는 것은 obj.sum(1,2)에 의해 obj 객체 안의 sum에 들어가있는 함수가 실행된 결과가 나오게 되었고 obj.sum에 의해 sum에 들어가 있는 함수를 구성하고 있는 코드들이 나오게 되었다는 사실이다. 이 사실을 통해 우리가 함수를 정의하고 함수를 호출하려고 할 때, 함수명 뒤에 ( )를 붙이느냐 안 붙이느냐에 따라 나오는 결과값이 달라진다는 것을 알 수 있다.
앞선 과정들을 통해 함수명 뒤에 ( )를 쓰지 않고 함수명만 쓰게되었을 때 해당 함수를 정의하는데 작성된 코드들이 나오게 된다는 것을 알 수 있었는데, 그렇다면 ( )의 의미는 무엇일까? ( )는 그냥 함수를 실행시키고 싶을 때 함수명과 함께 작성하는 녀석이라고 생각하면 된다.
( )를 붙이지 않고 함수명만을 사용해서 함수를 가져왔을 때 해당 함수가 실행되는 것이 아니라 그 함수를 구성하고 있는 코드 블록들을 가져오게 된다는 사실을 통해 우리는 함수를 어딘가에 담아서 사용이 가능하다는 것을 알 수 있다. 아래에서와 같이 특정 변수에 함수를 구성하는 코드들을 할당해서 사용하는 것이 가능한 것이다.
function aa (num1, num2) {
return num1 + num2
}
let ingoo = aa // 함수를 구성하고 있는 코드들이 ingoo라는 변수에 할당됨.
console.log('() 입력 x : ', ingoo)
console.log('() 입력 : ', ingoo())
aa 함수를 ingoo라는 변수에 할당했을 때, console.log(ingoo)의 결과 aa 함수를 구성하고 있는 코드블럭이 출력되는 것을 확인할 수 있고 console.log(ingoo( ))의 결과 NaN이 출력되는 것을 확인할 수 있다.
함수를 정의한 후 호출할 때 ( )가 있고 없고의 차이를 명확히 숙지하고 있어야 한다. 앞으로 함수를 사용할 때 ( ) 없이 사용하는 경우를 종종 보게 될 것이다. 이러한 방법은 함수를 호출하지 않고 어딘가에 담아 놓고 싶을 때 많이 사용하는 방법으로 위에서와 같이 특정 변수에 함수가 정의된 코드들이 할당되어 있게끔 만들 수 있다는 것을 인지하고 있어야 한다.
< 콜백 (callback) >
이제 우리의 본래 목적인 콜백(callback) 개념에 대해 알아보도록 하자.
콜백에는 2가지 유형이 존재하는데, 바로 동기식 콜백과 비동기식 콜백이다. 동기식과 비동기식의 차이를 명확히 알고 사용하기 위해서는 프로세스와 쓰레드 등 보다 깊은 내용들에 대해서도 자세히 알아야만 한다. 따라서 본 포스팅에서는 간략하게 동기식과 비동기식의 차이에 대해서만 언급한 후 전반적으로 콜백이 어떻게 사용되는지에 초점을 맞춰서 설명해 보고자 한다.
동기적으로 작동한다는 말은 쉽게 말해 코드가 반드시 작성된 순서 그대로 실행된다는 말이다. 이와 다르게 비동기식으로 작동한다는 것은 코드가 한줄 한줄 작성된 순서대로 실행되는 것이 아니라는 말이다. 즉, 프로그램이 비동기적으로 작동한다는 건, 쓰레드나 프로세스가 여럿이 돌고 있다는 뜻이 된다. 쉽게 말해 멀티태스킹이 구현되고 있다고 생각하면 조금 더 이해하기 수월할 것이다. 동기식 콜백과 비동기식 콜백에 대해서는 다음에 기회가 있을 때 다시 정리해 보기로 하고 오늘은 이 정도만 알아두고 넘어가도록 하자.
콜백은 매개변수에 함수가 들어오는 경우를 콜백(callback)이라고 한다. 함수를 정의하고 호출하는 과정들에 대해 앞에서 조금 살펴 보았는데 인자값에 함수를 집어넣는 경우가 콜백인 것이다. ( )를 사용하지 않고 인자값에 함수명만을 집어넣어 함수를 구성하고 있는 코드들을 인자값으로 집어넣게 되는 것이다. 아래 코드를 보고 좀 더 이해해 보도록 하자.
function test() {
console.log("hello world!")
}
function fn (type, param) {
console.log("'fn' 안에서 실행 : ", param)
if (type==='click') {
param() // 인자값으로 받은 함수를 실행시키고 싶다면 ()만 붙여주면 된다.
} else {
console.log('type을 click으로 입력해주세요.')
}
}
fn('click', test) // 함수 실행
"hello world!"를 출력하는 함수 test( )를 정의했고 type과 param을 매개변수로 하는 함수 fn( )을 정의했다. 함수 fn은 type과 param을 매개변수로 받는데 if문을 통해 만약 type==='click'일 경우에만 param( )이 실행되도록 코드를 작성하였다. 이렇게 함수 test( )와 fn( )을 정의한 후 fn('click', test)를 통해 함수 fn을 실행하면 아래와 같은 결과가 나오게 된다.
fn('click', test)를 살펴보면 매개변수 자리에 'click'이라는 문자열과 함수 test( )의 함수명이 들어간 것을 알 수 있다. 그 결과 if문에 앞서 작성된 console.log("'fn' 안에서 실행 : ", param)에 의해 param 자리에 들어간 함수 test( )를 구성하고 있는 코드블록이 출력된 것을 확인할 수 있다. 그리고 문자열 'click'을 매개변수로 받았기 때문에 if 조건문을 만족하게 되고 param( )에 의해 함수 test( )가 호출된 것을 확인할 수 있다. 여기서도 마찬가지로 test는 함수를 구성하고 있는 코드블록을 불러왔고 test( )는 함수를 실행시켰다는 것을 알 수 있다.
fn('click', test)
// 인자값으로 함수명만 작성해준다.
// 함수 test( )를 정의할 때 작성된 코드들만을 인자값으로 받게 된 것이다.
콜백 개념은 객체에서도 사용이 가능하다. 아래와 같이 elementObj라는 객체를 생성하였다고 하자.
let elementObj = {
addEventListener: fn
}
elementObj.addEventListener('click', test)
elementObj.addEventListener('click', function(){ console.log('익명함수') })
elementObj.addEventListener('click', () => { console.log('Arrow 함수 사용') })
elementObj 객체의 addEventListener 요소 안에 앞서 정의한 fn이라는 함수를 집어 넣어주면 elementObj.addEventListener( ) 와 같이 메소드 형태로 사용이 가능하다. 함수 fn은 매개변수로 문자열과 함수를 받았기 때문에 addEventListener( ) 메소드 역시 이 2개를 인자값으로 받게 된다. addEventListener( ) 메소드는 인자값으로 문자열과 함수를 받게 되는데 조금 더 자세히 살펴보면 elementObj.addEventListener('click', 함수코드) 의 형태가 되는 것이다. 즉, 인자값으로 함수코드를 입력해 주는 것이라고 이해하고 있어야 한다. 그리고 인자값으로 함수코드를 넣어주는 방법으로는 위의 코드에 나와있는 것과 같이 다음의 세가지 방법이 있다.
- 함수를 정의한 다음에 함수명만 작성해서 입력하는 방법
- 익명함수를 바로 작성해서 입력하는 방법
- 익명함수를 Arrow 함수로 바꿔서 입력하는 방법
이상으로 콜백(callback) 개념에 대해 알아보았는데 콜백에 대해 요약하자면, 콜백(callback)은 인자값에 함수를 넣어서 함수 안에서 다른 함수를 실행시키고 싶을 때 사용하는 것이다.
'JavaScript' 카테고리의 다른 글
JavaScript - DOM (2) (0) | 2022.01.12 |
---|---|
JavaScript - DOM (1) (0) | 2022.01.10 |
JavaScript - 얕은복사 , 깊은복사 (0) | 2022.01.07 |
JavaScript기초 - 정리(4) 배열(array) , 객체(object) (0) | 2022.01.04 |
JavaScript기초 - 정리(3) 변수 선언 , 이스케이프 문자 , else if문 , 함수 (0) | 2022.01.04 |