콜백

콜백 에서 JavaScript

2개의 연습 문제

콜백 소개

콜백 함수는 다른 함수에 인자로 전달되는 함수예요. 그러면 콜백 함수를 호출해서 뒤따르는 동작을 실행할 수 있어요. 콜백은 어떤 작업의 결과를 처리하거나, 이벤트가 발생했을 때 동작을 처리할 때 자주 사용해요. 콜백 함수는 동기 프로그래밍과 비동기 프로그래밍 모두에서 사용할 수 있어요.

const sideLength = 5;

// Caller function takes a callback function
function applySideLength(callback) {
  return callback(sideLength);
}

// Callback must expect the possible argument from the calling function
function areaOfSquare(side) {
  return side * side;
}

applySideLength(areaOfSquare); // => 25

콜백을 함수 표현식으로 작성할 수도 있어요:

applySideLength(function squarePerimeter(side) {
  return side * 4;
});

JavaScript는 한 번에 하나의 함수 호출만 실행할 수 있는 단일 스레드 런타임으로 설계되었기 때문에, 이 패턴은 JavaScript에서 유용해요. 함수가 실행되는 동안에는 그 함수가 반환되기 전까지 런타임이 다른 이벤트에 응답하거나 실행을 이어갈 수 없어요.

많은 API 호출(I/O 함수, 타이머, 이벤트 리스너)은 작업이 끝날 때까지 현재 함수 호출을 잠시 옆으로 밀어 두는 비동기 방식을 사용해요. 작업이 완료되면 콜백 함수가 메시지 큐에 놓이고, 런타임이 함수 호출 사이에 있을 때 이 메시지들이 콜백 함수를 호출함으로써 처리돼요.

콜백 함수는 나중에 호출되는 함수에서는 접근할 수 없는 클로저 스코프의 변수를 참조할 수 있기 때문에 유용하기도 해요.

콜백 함수의 구체적인 예

이벤트 핸들러

이벤트 핸들러는 JavaScript에서 콜백의 흔한 사용 사례예요. 'onload'나 'onclick' 같은 브라우저 이벤트는 함수를 호출하도록 트리거할 수 있는 신호예요. DOM [문서 객체 모델 객체의 addEventListener 메서드는 이벤트가 발생했다는 것을 "듣게" 되었을 때 호출할 콜백 함수를 등록해요.

document.addEventListener('onload', function () {
  alert('The webpage has now been loaded');
});

Node.js 관례

Node.js에서는 콜백 함수가 프로그램의 흐름을 제어하기 위한 관례를 따라요. 이 관례는 이런 패턴을 따라요. 콜백 함수의 첫 번째 인자는 Error나 null을 받을 수 있고, 두 번째 이후의 인자는 호출한 함수가 보내도록 설계된 데이터를 받아요.

오류가 발생하면 두 번째 이후의 인자가 없을 수도 있으므로, 그 인자가 있다고 가정하면 안 돼요.

function operation(a, b, callback) {
  // Work ...

  if (/* an error occurs */) {
    return callback(new Error('An error occurred'))
  }

  // On success:
  callback(null, data)
}

function callback(error, returnedData) {
  if (error) {
    // An error occurred, handle it here.
    return
  }

  // No error occurred, continue with the returned data.
}

operation(1, 2, callback)

비동기 함수를 다루면서 흐름 제어를 도울 때 이 패턴을 자주 보게 돼요.

알고 보면 콜백

자주 쓰이는 Array 함수들은 콜백 함수로 동작을 정의해요:

  • Array.prototype.forEach:

    • 콜백을 받아서, 배열의 각 요소에 콜백을 적용해요.

      [1, 2, 3].forEach(function (element) {
        doSomething(element);
      });
      // => doSomething() is invoked 3 times, once with each element
      
  • Array.prototype.map

    • 콜백을 받아서, 배열의 각 요소에 콜백을 적용하고 그 결과로 새 배열을 만들어요.

      [1, 2, 3].map(function (element) {
        return element + 1;
      });
      // => [2, 3, 4]
      
  • Array.prototype.reduce

    • 콜백을 받아서, 배열의 각 요소에 콜백을 적용하고 그 결과를 다음 호출로 넘겨줘요.

      [1, 2, 3].reduce(function (runningSum, element) {
        return runningSum + element;
      }, 0);
      // => 6
      
GitHub에서 편집 링크가 새 창이나 탭에서 열려요

콜백 배우기