콜백: 두 판 사이의 차이

내위키
편집 요약 없음
편집 요약 없음
40번째 줄: 40번째 줄:
</source>
</source>


<code>count()</code> 함수가 콜백함수를 매개변수로 받도록 하고, 숫자를 출력하는 부분을 <code>hello()</code>, <code>goodbye()</code> 콜백함수로 따로 분리했다. 그리고 <code>main()</code> 함수에서는 처음에는 <code>hello() 함수를 콜백으로 전달해서 <code>count()</code> 함수를 실행시키고 다음에는 <code>goodbye()</code> 함수를 콜백으로 <code>count()</code> 함수를 실행시킨다. 이제 <code>count()</code>는 직접 출력을 처리하지 않고 숫자가 1 증가할 때마다 전달 받은 콜백함수만 부른다. 콜백함수를 어떻게 만드느냐에 따라 출력 형식을 바꿀 수도 있고 출력이 아닌 다른 일을 할 수도 있지만 <code>count()</code> 함수 내부에는 영향을 미치지 않는다. 게임기에 팩만 갈아끼워 주면 다양한 게임을 즐길 수 있는 것과 비슷하다.
<code>count()</code> 함수가 콜백함수를 매개변수로 받도록 하고, 숫자를 출력하는 부분을 <code>hello()</code>, <code>goodbye()</code> 콜백함수로 따로 분리했다. 그리고 <code>main()</code> 함수에서는 처음에는 <code>hello()</code> 함수를 콜백으로 전달해서 <code>count()</code> 함수를 실행시키고 다음에는 <code>goodbye()</code> 함수를 콜백으로 <code>count()</code> 함수를 실행시킨다. 이제 <code>count()</code>는 직접 출력을 처리하지 않고 숫자가 1 증가할 때마다 전달 받은 콜백함수만 부른다. 콜백함수를 어떻게 만드느냐에 따라 출력 형식을 바꿀 수도 있고 출력이 아닌 다른 일을 할 수도 있지만 <code>count()</code> 함수 내부에는 영향을 미치지 않는다.


콜백이 주로 쓰이는 경우는 함수 또는 컴포넌트 간의 통신이다. 예를 들어, 프로그램에서 + 버튼을 누를 때마다 숫자가 1씩 올라가도록 표시하는 컴포넌트가 있다고 가정해 보자. 버튼이 눌리는 이벤트가 발생할 때 버튼이 직접 해당 컴포넌트를 조작하도록 할 수도 있지만, 같은 버튼을 눌렀을 때 내용이 업데이트 되어어 할 컴포넌트가 한 개 이상일 수도 있고, 상황에 따라 그런 컴포넌트의 갯수가 바뀔 수도 있다. 버튼 쪽에서 이걸 다 감안해서 코드를 넣으면 상호 의존성이 커지고<ref>의존성이 커지면 버그가 있을 때 문제 해결이 복잡해진다. 프로그래머들은 상호 의존성을 줄이기 위해 별별 짓을 다 한다.</ref> 효율이 떨어진다. 그보다는 이러한 컴포넌트들이 버튼이 눌렸을 때 해야 할 동작을 콜백함수 안에 넣고, 이를 버튼에 넘겨주면 버튼이 눌렸을 때 그냥 콜백함수만 불러주면 된다.
콜백이 주로 쓰이는 경우는 함수 또는 컴포넌트 간의 통신이다. 예를 들어, 프로그램에서 + 버튼을 누를 때마다 숫자가 1씩 올라가도록 표시하는 컴포넌트가 있다고 가정해 보자. 버튼이 눌리는 이벤트가 발생할 때 버튼이 직접 해당 컴포넌트를 조작하도록 할 수도 있지만, 같은 버튼을 눌렀을 때 내용이 업데이트 되어어 할 컴포넌트가 한 개 이상일 수도 있고, 상황에 따라 그런 컴포넌트의 갯수가 바뀔 수도 있다. 버튼 쪽에서 이걸 다 감안해서 코드를 넣으면 상호 의존성이 커지고<ref>의존성이 커지면 버그가 있을 때 문제 해결이 복잡해진다. 프로그래머들은 상호 의존성을 줄이기 위해 별별 짓을 다 한다.</ref> 효율이 떨어진다. 그보다는 이러한 컴포넌트들이 버튼이 눌렸을 때 해야 할 동작을 콜백함수 안에 넣고, 이를 버튼에 넘겨주면 버튼이 눌렸을 때 그냥 콜백함수만 불러주면 된다.

2020년 11월 14일 (토) 23:16 판

Callback.

콜백함수(callback function)라고도 부른다. 프로그래밍 언어에서 함수의 매개변수(인수)로 전달되는 함수로, 콜백함수를 매개변수로 받은 함수 또는 객체는 이를 적절한 시기에 실행시킬 수 있다.

Dart 언어에서 콜백함수를 쓰는 간단한 예를 보면,

void count(int number){
  for (int i = 0; i < 5; i++) {
    print('hello ${i + 1}');
  }
}

void main() {
  count(5);
}

콜백함수를 쓰지 않을 때에는 for 루프로 변수의 값을 1씩 증가시키는 부분과, 변수의 값을 출력하는 부분이 모두 count() 함수 안에 들어가 있다.

void hello(int i) {
  print('hello ${i + 1}');
}

void goodbye(int i) {
  print('goodbye ${i + 1}');
}

void count(int number, void Function(int) callback){
  for (int i = 0; i < 5; i++) {
    callback(i);
  }
}

void main() {
  count(5, hello);
  count(5, goodbye);
}

count() 함수가 콜백함수를 매개변수로 받도록 하고, 숫자를 출력하는 부분을 hello(), goodbye() 콜백함수로 따로 분리했다. 그리고 main() 함수에서는 처음에는 hello() 함수를 콜백으로 전달해서 count() 함수를 실행시키고 다음에는 goodbye() 함수를 콜백으로 count() 함수를 실행시킨다. 이제 count()는 직접 출력을 처리하지 않고 숫자가 1 증가할 때마다 전달 받은 콜백함수만 부른다. 콜백함수를 어떻게 만드느냐에 따라 출력 형식을 바꿀 수도 있고 출력이 아닌 다른 일을 할 수도 있지만 count() 함수 내부에는 영향을 미치지 않는다.

콜백이 주로 쓰이는 경우는 함수 또는 컴포넌트 간의 통신이다. 예를 들어, 프로그램에서 + 버튼을 누를 때마다 숫자가 1씩 올라가도록 표시하는 컴포넌트가 있다고 가정해 보자. 버튼이 눌리는 이벤트가 발생할 때 버튼이 직접 해당 컴포넌트를 조작하도록 할 수도 있지만, 같은 버튼을 눌렀을 때 내용이 업데이트 되어어 할 컴포넌트가 한 개 이상일 수도 있고, 상황에 따라 그런 컴포넌트의 갯수가 바뀔 수도 있다. 버튼 쪽에서 이걸 다 감안해서 코드를 넣으면 상호 의존성이 커지고[1] 효율이 떨어진다. 그보다는 이러한 컴포넌트들이 버튼이 눌렸을 때 해야 할 동작을 콜백함수 안에 넣고, 이를 버튼에 넘겨주면 버튼이 눌렸을 때 그냥 콜백함수만 불러주면 된다.

비동기처리를 할 때에도 많이 쓰이는데, CPU와 메모리 사이의 작업에 비해서 보조기억장치, 네트워크와 통신하는 작업은 훨씬 시간이 오래 걸리는데 예를 들어 네트워크로 요청을 보내서 답을 받을 때까지 컴퓨터 자원은 그냥 멍때리고 있어야 한다. 이 때문에 요청을 보내놓고 컴퓨터는 다른 일을 하다가 답이 왔을 때 이를 처리하는 비동기 프로그래밍을 많이 사용하는데, 프로그래밍 언어에서 비동기 프로그래밍 지원을 하지 않는 경우에는 콜백함수로 비슷한 효과를 내는 경우가 많으며, 프로그래밍 언어에서 비동기 지원을 하는 경우라도 리스너 패턴을 비롯한 다양한 방법으로 콜백함수를 쓰게 된다.

각주

  1. 의존성이 커지면 버그가 있을 때 문제 해결이 복잡해진다. 프로그래머들은 상호 의존성을 줄이기 위해 별별 짓을 다 한다.