왜 "콜백 함수"가 필요합니까?


16

나는 책을 읽고있다 programming in Lua. 그것은 말했다

클로저는 많은 상황에서 유용한 도구를 제공합니다. 우리가 보았 듯이, 그것들은 sort와 같은 고차 함수에 대한 인수로 유용합니다. 클로저는 newCounter 예제와 같이 다른 함수도 빌드하는 함수에 유용합니다. 이 메커니즘을 통해 Lua 프로그램은 기능적 세계의 정교한 프로그래밍 기술을 통합 할 수 있습니다. 클로저는 콜백 함수에도 유용합니다. 일반적인 GUI 툴킷에서 버튼을 만들 때 일반적인 예가 발생합니다. 각 버튼에는 사용자가 버튼을 누를 때 호출되는 콜백 기능이 있습니다. 다른 버튼을 눌렀을 때 약간 다른 작업을 수행하려고합니다. 예를 들어, 디지털 계산기에는 숫자마다 하나씩 10 개의 유사한 버튼이 필요합니다. 다음과 같은 기능으로 각각을 만들 수 있습니다.

function digitButton (digit)
  return Button{label = tostring(digit),
                action = function ()
                  add_to_display(digit)
                  end}
end

를 호출하면 (이것은 클로저를 생성합니다)를 digitButton반환 action하므로 digit전달 된에 액세스 할 수 있습니다 digitButton.

내 질문은 :

Why we need call back functions? what situations can I apply this to?


저자는 말했다 :

이 예제에서는 Button이 새 버튼을 만드는 툴킷 함수라고 가정합니다. label은 버튼 레이블입니다. action은 버튼을 눌렀을 때 호출되는 콜백 클로저입니다. digitButton이 작업을 수행 한 후 로컬 변수 숫자가 범위를 벗어난 후 콜백을 오랫동안 호출 할 수 있지만 여전히이 변수에 액세스 할 수 있습니다.

저자에 따르면 비슷한 예가 다음과 같다고 생각합니다.

function Button(t)
  -- maybe you should set the button here
  return t.action -- so that you can call this later
end

function add_to_display(digit)
  print ("Display the button label: " .. tostring(digit))
end

function digitButton(digit)
  return Button{label = tostring(digit),
                action = function ()
                           add_to_display(digit)
                           end}
end

click_action = digitButton(10)
click_action()

그러므로, the callback can be called a long time after digitButton did its task and after the local variable digit went out of scope.


답변:


45

Guy 1 to Guy 2 : 사용자가 거기를 클릭 할 때 무언가를하고 싶을 때 다시 전화를 걸까요?

Guy 2는 사용자가 여기를 클릭하면 Guy 1을 다시 호출합니다.


1
나는이 콜백 농담을 매우 좋아한다 :-P
Lucas Li

6
나 뿐인가요? 이것이 왜 콜백 함수가 필요한지 설명하는 방법을 얻지 못했습니다.
phant0m

2
Guy 1이 Guy 2에게 "시간이 옳은 때"라고 말하는 것과 비슷합니다. Guy 2는 그의 하루를 보냈으며 시간이 옳았을 때 그렇게했습니다. Guy 1이 Guy 2의 발신자임을 의미 한 경우 Guy 2가 Guy 1을 다시 호출하지 않기 때문에 잘못된 것입니다. 실제로 Guy 1이 Guy 2의 발신자 인 경우이 시나리오에서 손을 떼지 않아도됩니다. Guy 1이 콜백을 의미했다면 콜백은 Guy 2가 누구인지 모르고 확실하게 전화를 요청하지 않기 때문에 올바르지 않습니다.
rism

이것은 끔찍한 설명입니다.
insidesin

21

아니요, 액션을 반환 하지 않습니다 . 사용자가 클릭하면 버튼이 실행 됩니다. 그게 답입니다. 제어하지 않는 이벤트 (시스템의 일부인 이벤트 루프는 버튼의 메소드를 실행하여 결과적으로 실행 됨)에 대해 다른 컴포넌트에서 발생해야하는 조치를 정의 할 때 콜백 함수가 필요합니다. 행동).


나는 당신에 동의하지 않습니다. 게시물을 수정하고 코드를 추가했습니다. 여전히 조치가 즉시 실행되지 않는다고 생각합니다.
Lucas Li

2
Tim, 당신 말이 맞지만 Jan도 마찬가지입니다. "사용자가 버튼을 클릭하면 버튼이 즉시 실행됩니다".
AlexanderBrevig

@AlexanderBrevig 예, 여전히 Jan의 답장이 매우 유용하다고 생각합니다. 콜백과 콜백이 필요한 이유를 알려줍니다.
Lucas Li

콜백은 누군가가 두 번째 함수에 추가 한 첫 번째 이름으로, 첫 번째 함수가 실행될 때 기준에 따라 불명확 한 이름입니다. well_done () 함수를 호출하면 차이가 없습니다. 콜백은 확인하는 것과 같습니다. 확인은 일련의 메시지 (보통 2 개)이며 콜백은 함수의 보안 (보통 2 개)입니다. 3 개 이상의 콜백을 연결하고 축하합니다. 어려운 일을하고 싶습니다.
m3nda

16

콜백을 사용하는 더 좋은 예는 비동기 함수에 있다고 생각합니다. Lua를 말할 수는 없지만 JavaScript에서 가장 일반적인 비동기 작업 중 하나는 AJAX를 통해 서버에 연결하는 것입니다.

AJAX 호출은 비동기 적입니다. 다음과 같이하면 의미가 있습니다.

var ajax = ajaxCall();
if(ajax == true) {
  // Do something
}

if블록 의 내용은 올바르게 올바르게 실행되지 않으며, ajaxCall()실행되면 if명령문에 도달하기 전에 함수가 완료 되었기 때문 입니다.

그러나 콜백은 필요한 함수를 호출하기 전에 비동기 호출이 완료되도록하여이 문제를 해결합니다. 따라서 코드는 다음과 같이 변경됩니다.

function ajaxCallback(response) {   
  if(response == true) {
    // Do something   
  }
}

ajaxCall(ajaxCallback);

이것의 목적은 인터페이스 그리기와 같은 다른 것들을 방해하지 않고 데이터 수집과 같은 일을 할 수 있도록하는 것입니다. 데이터 수집이 동기화 된 경우, 애플리케이션이 데이터를 얻기 위해 대기 할 때 인터페이스가 응답하지 않게됩니다. 응답이없는 인터페이스는 대부분의 사용자가 응용 프로그램이 "충돌되었다"고 프로세스를 종료하려고 시도하기 때문에 사용자 경험에 매우 나쁩니다.

이것을 실제로 보려면 전체 페이지를 다시로드하지 않고 모든 종류의 업데이트를 수행하는 웹 사이트를 살펴보십시오. Twitter, LinkedIn 및 StackExchange 사이트가 좋은 예입니다. 피드의 Twitter의 "무한 스크롤"및 SE의 알림 (사용자 알림 및 질문에 새로운 활동이있는 알림 모두에 대한)은 비동기 호출에 의해 제공됩니다. 어딘가에 스피너가 보이면 섹션이 비동기 호출을하고 해당 호출이 완료되기를 기다리는 중이지만 인터페이스의 다른 항목과 상호 작용할 수 있으며 다른 비동기 호출을 수행 할 수도 있습니다. 호출이 완료되면 이에 따라 인터페이스가 반응하고 업데이트됩니다.


12

당신은 질문을했다

왜 "콜백 함수"가 필요한가?

간결하고 명확한 방법으로 답변을 드리겠습니다 (실패한 경우이 답변 하단의 wiki 링크를 참조하십시오).

콜백은 특정 구현을 마지막 순간까지 연기하는 데 사용됩니다.

버튼 예제는 이에 대한 좋은 예입니다. 응용 프로그램에 페이지를 프린터로 인쇄하는 버튼을 원한다고 가정 해보십시오 PrinterButton.이 작업을 수행하기 위해 완전히 새로운 클래스 를 코딩 해야하는 세상을 상상할 수 있습니다.

운 좋게도 콜백이라는 개념이 있습니다 (상속성과 템플릿 패턴 의 사용은 일종의 콜백 의미론 적이므로).

버튼의 모든 측면을 다시 구현하는 대신 버튼 구현에 추가해야합니다. 는 Button일의 개념이 무엇인가를 누를 때를. 우리는 단순히 그것이 무엇인지 말해줍니다.

동작을 프레임 워크에 주입하는 메커니즘을 콜백이라고합니다.

예:

HTML 버튼에 동작을 삽입 해 봅시다 :

<button onclick="print()">Print page through a callback to the print() method</button>

이 경우 onclick콜백을 가리 킵니다 print(). 이 예에서는 메소드입니다.


http://en.wikipedia.org/wiki/Callback_(computer_programming)


고맙게도, 당신의 그림을 읽은 후에는 동기식 콜백 예제 인 위키를 읽습니다.
Lucas Li

문제가있을 때마다 함수에 응답을 알려주고 문제를 들어야합니다. 스스로 해결하는 문제를 해결하는 기능을 가르치십시오.
Joe

8

콜백 함수가 필요한 이유는 무엇입니까? 어떤 상황에 적용 할 수 있습니까?

콜백 함수는 이벤트 중심 프로그래밍에 매우 유용합니다. 이벤트가 올바른 코드를 트리거하는 방식으로 프로그램을 설정할 수 있습니다. 사용자가 UI의 모든 요소 (예 : 단추 또는 메뉴 항목)를 클릭 할 수 있고 적절한 코드가 실행되는 GUI가있는 프로그램에서 매우 일반적입니다.


1
+ 그것이 콜백이 좋은 점이지만, 나는 그것들을 써야하는 것을 싫어한다 :-)
Mike Dunlavey

내가 신입생이었을 때, 선생님은 우리에게 MFC에서 프로그래밍하는 법을 가르쳐 주셨지만 콜백이 무엇인지 말씀 해주지 않으 셨습니다 :-(
Lucas Li

2

콜백없이 발생하는 일 :

Guy 1 : 좋아, 나는 그 일이 일어나기를 기다리고 있습니다. (휘슬, 트위들 엄지 손가락)

가이 2 : 젠장! Guy 1이 왜 물건을 보여주지 않습니까? 일이 벌어지는 것을보고 싶다 !! 내 물건 어 Where 어? 이 주변에서 어떻게해야합니까?


1

첫째, 콜백이라는 용어는 무언가에 사용되는 클로저를 말합니다.

예를 들어, 클로저 함수를 만들어 변수에 저장한다고 가정 해 봅시다. 어떤 용도로도 사용되지 않기 때문에 콜백이 아닙니다.

그러나 클로저를 만들어 무언가가 발생할 때 호출 될 수있는 곳에 저장한다고 가정 해 봅시다. 이제 콜백이라고합니다.

일반적으로 콜백은 호출하는 부분과 다른 부분에 의해 생성됩니다. 따라서 프로그램의 일부가 다른 부분을 "콜백"한다고 쉽게 상상할 수 있습니다.

간단히 말해서, 콜백을 통해 프로그램의 한 부분이 다른 부분에 무언가 발생했을 때 무언가를하도록 지시 할 수 있습니다.

클로저에 사용되어 변수가 계속 유지되는 것과 같이, 이는 루아 어를 사용하지 않는 사람들 사이에서 "가치 로컬 변수의 수명 연장"이라는 완전히 다른 기능입니다. 그리고 그것은 또한 매우 유용합니다.


예, Extending the lifetime of local variables또한 용어를 말합니다 upvalue.
Lucas Li

흠, 흥미로운. 빠른 Google 검색에서 때때로 다른 언어를 설명하는 데 사용 된 것으로 나타 났지만 upvalue 라는 용어 는 Lua에만 해당되는 것 같습니다. 내 답변에 추가하겠습니다.
Jonathan Graef

1

콜란은 적어도 포트란 초기부터 시작되었습니다. 예를 들어 Runge-Kutta 솔버와 같은 ODE (일반 미분 방정식) 솔버가있는 경우 다음과 같이 보일 수 있습니다.

subroutine rungekutta(neq, t, tend, y, deriv)
  integer neq             ! number of differential equations
  double precision t      ! initial time
  double precision tend   ! final time
  double precision y(neq) ! state vector
  ! deriv is the callback function to evaluate the state derivative
  ...
  deriv(neq, t, y, yprime) ! call deriv to get the state derivative
  ...
  deriv(neq, t, y, yprime) ! call it several times
  ...
end subroutine

호출자는 필요할 때 호출 될 특수 목적 함수를 전달하여 서브 루틴의 작동을 사용자 정의 할 수 있습니다. 이를 통해 ODE 솔버를 사용하여 다양한 시스템을 시뮬레이션 할 수 있습니다.


1

이것을 우연히 발견하고 더 최신의 답변을 제공하고 싶었습니다 ...

콜백 함수를 사용하면 나중에 데이터로 무언가를 할 수 있으므로 코드의 나머지 부분을 기다리지 않고 실행할 수 있습니다. 비동기 코드를 사용하면 나중에 아무 것도 실행하지 않아도 됩니다 . 내가 접한 콜백 함수의 가장 읽기 쉬운 예제는 JavaScript의 약속입니다. 아래 예제에서 function (result) 또는 (newResult) 또는 (finalResult)가 표시 될 때마다 콜백 함수입니다. 중괄호 안의 코드는 서버에서 데이터가 다시 들어 오면 실행됩니다. 이 시점에서만 필요한 데이터를 사용할 수 있으므로 이러한 기능을 실행하는 것이 좋습니다.

doSomething().then(function(result) {
  return doSomethingElse(result);
})
.then(function(newResult) {
  return doThirdThing(newResult);
})
.then(function(finalResult) {
  console.log('Got the final result: ' + finalResult);
})
.catch(failureCallback);

코드는 다음과 같습니다 ... https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises

바라건대, 이것은 누군가를 돕는다. 이것이 ME가 콜백을 이해하는 데 도움이 된 것입니다. :)


1
이것은 이전의 9 가지 답변에서 언급되고 설명 된 내용에 비해 실질적인 내용을 제공하지 않는 것 같습니다
gnat

1
어쩌면 당신에게는 이것이 콜백을 분명하게 만들어 주었으므로 공유 할 것이라고 생각했습니다. IMO는 예제의 가독성으로 인해 가치가 있습니다. 우리는 코드의 가독성이 특히 초보자에게 먼 길을 가고 있다는 데 동의 할 수 있다고 확신합니다.
NRV

-2

루아는 모르지만 일반적으로 콜백 메소드에는 멀티 스레딩과 같은 것이 있습니다. 예를 들어 모바일 응용 프로그램 개발 프로그래밍에서 대부분의 응용 프로그램은 서버에 요청을 보내고 서버에서 데이터로 응답 한 데이터를 사용하여 UI를 재생하는 것처럼 작동합니다. 사용자가 서버로 요청을 보내면 서버에서 응답을받는 데 시간이 걸리지 만 최상의 UX UI를 유지하려면 멈춰서는 안됩니다.

이 때문에 여러 스레드를 사용하여 병렬 작업을 수행합니다. 서버에서 응답을 받으면 UI를 업데이트해야합니다. 업데이트하려면 해당 스레드에서 알려야합니다. 기능적인 세계에서. 이러한 유형의 함수 호출을 콜백 메소드라고합니다. 이 메소드를 호출하면 컨트롤이 메인 스레드로 돌아와야합니다. 예를 들어 콜백 메소드는 objective-C의 블록입니다.


예, 당신이 말한 것은 책을 읽은 후 나의 이해와 일치합니다.
Lucas Li

2
콜백 메소드는 멀티 스레딩과 다릅니다. 콜백 메소드는 단순히 함수 포인터 (위임)입니다. 스레드는 CPU 컨텍스트 전환 / 이용에 관한 것입니다. 스레딩은 UX의 CPU 최적화에 관한 것이고 콜백은 다형성의 메모리 전환에 관한 것입니다. 스레드가 콜백을 실행할 수 있다고해서 스레딩과 콜백이 유사하다는 의미는 아닙니다. 스레드는 정적 클래스에서 정적 메서드도 실행하지만 스레딩 및 정적 형식은 비슷하지 않습니다.
rism
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.