Home 콜백 함수 Callback
Post
X

콜백 함수 Callback

Javascript에서의 Callback 함수에 대해 알아보자.


Callback 함수란?

  • 다른 코드의 인자로 넘겨지는 실행 가능한 코드
  • 어떤 이벤트에 의해 호출 되어지는 함수

종합해보면 다른 코드가 호출해서 인수를 넘겨주면 실행되는 함수를 말합니다.


Callback 함수의 구조

특정 함수의 매개변수 값으로 Callback 함수가 들어온다.

특정 함수의 처리 결과값이 Callback 함수의 매개값으로 주어진다.

Callback 함수가 실행된다.

1
2
3
4
5
6
7
8
9
10
11
function printName(name) {
  console.log(`my name is ${name}`);
}

function name(callback) {
  var a = "Psmin";

  callback(a);
}

name(printName); // my name is Psmin
  • name이라는 특정 함수의 매개변수로 Callback 함수 (printName 함수)가 들어간다.
  • 변수 a에 담겨진 Psmin가 callback 함수(printName 함수)의 매개값으로 주어진다.
  • callback 함수(printName 함수)가 실행된다.

Callback 함수를 사용하는 이유

  • 함수의 구조적 설계

    Callback 함수는 주로 함수의 내부의 수행결과를 함수 외부로 보낼 때 사용하게 됩니다.

    로직 처리 부분과 나머지 부분을 구분하는 것이 가능해 함수를 구조적으로 설계할 목적으로 사용합니다.

    특정 역할을 수행하는 함수와 조립하거나 함수 수정 및 재사용이 용이해지는 장점이 있습니다.

  • 비동기 처리

    비동기 처리란 요청 시 응답을 기다리지 않고 다음 작업을 이어서 진행하는 처리 방식을 말합니다.

    Callback 함수를 이용해 비동기 처리를 구현할 수 있습니다.

  • 이벤트 처리

    Javascript에서 이벤트란 마우스 Click, 키보드 입력, 특정 item에 마우스 hover 등이 있습니다.

    사용자가 이벤트를 발생시킬 때 이벤트 처리 함수(eventListener)가 실행되어야 하기 때문에 Callback 함수를 이용해 이를 구현할 수 있습니다.


Callback 함수의 예시

  • Callback 함수없이 구현

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    
    function add(a, b) {
      return a + b;
    }
    
    function result_ko(result) {
      return "결과 = " + result;
    }
    
    function result_en(result) {
      return "result = " + result;
    }
    
    function print_ko(a, b) {
      var val = add(a, b);
      var result = result_ko(val);
      console.log(result);
    }
    
    function print_en(a, b) {
      var val = add(a, b);
      var result = result_en(val);
      console.log(result);
    }
    
    print_ko(1, 1);
    print_en(1, 1);
    
  • Callback 함수로 구현

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    function add(a, b) {
      return a + b;
    }
    
    function result_ko(result) {
      return "결과 = " + result;
    }
    
    function result_en(result) {
      return "result = " + result;
    }
    
    function print(a, b, callback) {
      var val = add(a, b);
      var result = callback(val);
      console.log(result);
    }
    
    print(1, 1, result_ko);
    print(1, 1, result_en);
    

Callback 방식의 비동기 처리 단점

  • 콜백 지옥

    함수의 매개변수로 Callback 함수가 반복되어 코드의 들여쓰기가 깊어지는 현상을 말합니다.

    주로 비동기 작업 처리(이벤트 처리, 서버 통신)에서 발생합니다.

    콜백 지옥이 심한 코드는 가독성이 떨어지고 수정이 어려워 유지보수하기 힘들어집니다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    step1(function (err, value1) {
      if (err) {
        console.log(err);
        return;
      }
      step2(function (err, value2) {
        if (err) {
          console.log(err);
          return;
        }
        step3(function (err, value3) {
          if (err) {
            console.log(err);
            return;
          }
          step4(function (err, value4) {
            // 정신 건강을 위해 생략
          });
        });
      });
    });
    

    만일 비동기 함수의 처리 결과를 가지고 다른 비동기 함수를 호출해야 하는 경우, 함수의 호출이 중첩이 되어 복잡도가 높아지는 현상이 발생할 수 있습니다.

  • 에러 처리의 한계

    1
    2
    3
    4
    5
    6
    7
    
    try {
      setTimeout(() => {
        throw new Error("가상 에러");
      }, 1000);
    } catch (error) {
      console.log(error);
    }
    

    위 예제는 try 블록에서 setTimeout 함수가 실행되면 1초 후에 콜백 함수가 실행되어 가상에러를 발생시킨다.

    그러나 catch 블록은 해당 에러를 잡아내지 못합니다.

    비동기 처리 함수의 콜백 함수는 조건(timer함수의 tick이벤트 등)이 발생하면 Task queue(테스크 큐)로 이동한 후 호출 스택이 비어졌을 때, 이동되어 실행됩니다.

    setTimeout 함수는 비동기 함수로 콜백 함수가 실행되기 전 즉시 종료되어 호출 스택에서 제거됩니다.

    이후 tick 이벤트가 발생하면 setTImeout 함수의 콜백 함수는 Task queue로 이동한 후 호출 스택이 비어졌을 때 이동되어 실행됩니다.

    이 때, setTimeout 함수는 호출 스택에서 제거된 상태이므로 콜백 함수의 호출자(caller)가 아닌 상태입니다.

    발생한 에러(exception)는 호출자 방향으로 전파되기 떄문에 catch 블록에서 에러가 캐치되지 않고 프로세스는 종료됩니다.


이러한 단점을 보안하기위해 Promise, async/await 패턴 등이 표준처럼 사용되고 있습니다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.