콜백 함수 란 무엇입니까?


684

콜백 함수 란 무엇입니까?


8
당신은 여기에서 찾을 수 있습니다 : stackoverflow.com/a/9652434/3343174 콜백에 대한 최고의 설명
Fakher


자세한 설명은 두 번째 답변을 참조하십시오
Donato

내가 찾은 콜백에 대한 최고의 설명 youtube.com/watch?v=xHneyv38Jro
Sameer Sinha

답변:


681

개발자는 종종 망할 물건의 이름 때문에 콜백이 무엇인지 혼동합니다.

콜백 함수는 다음과 같은 함수입니다.

  • 다른 기능으로 액세스 가능
  • 첫 번째 함수가 완료되면 첫 번째 함수 다음에 호출됩니다.

콜백 함수의 작동 방식을 이해하는 좋은 방법은 함수가 전달 된 함수의 " 뒤에 호출되는 "함수 라는 것입니다.

더 나은 이름은 "call after" 함수일 것입니다.

이 구문은 이전 이벤트가 완료 될 때마다 활동을 수행하려는 비동기 동작에 매우 유용합니다.

의사 코드 :

// A function which accepts another function as an argument
// (and will automatically invoke that function when it completes - note that there is no explicit call to callbackFunction)
funct printANumber(int number, funct callbackFunction) {
    printout("The number you provided is: " + number);
}

// a function which we will use in a driver function as a callback function
funct printFinishMessage() {
    printout("I have finished printing numbers.");
}

// Driver method
funct event() {
   printANumber(6, printFinishMessage);
}

event ()를 호출 한 경우의 결과 :

The number you provided is: 6
I have finished printing numbers.

여기서 출력 순서는 중요합니다. 콜백 함수가 나중에 호출되므로 "번호 인쇄를 마쳤습니다"가 맨 처음이 아닌 마지막에 인쇄됩니다.

콜백은 포인터 언어와 함께 사용되기 때문에 소위 호출됩니다. 그중 하나를 사용하지 않으면 '콜백'이라는 이름을 사용하지 마십시오. 부모 메소드가 호출 될 때 (버튼 클릭, 타이머 틱 등의 조건이 무엇이든) 메소드 본문이 완료되도록 다른 메소드에 인수로 제공되는 메소드를 설명하는 것은 단지 이름이라는 것을 이해하십시오. 콜백 함수가 호출됩니다.

일부 언어는 여러 개의 콜백 함수 인수가 지원되는 구문을 지원하며 부모 함수가 완료되는 방식에 따라 호출됩니다 (예 : 부모 함수가 성공적으로 완료되면 하나의 콜백이 호출되고 부모 함수가 특정 오류 등).


31
귀하의 예는 훌륭하지만 용어가 "콜백"인 이유를 모르겠습니다. 의미 OfLife는 언제 "환불"됩니까?
CodyBugstein

4
님, 안녕하세요 once its parent method completes, the function which this argument represents is then called. 따라서 함수가 인수로 다른 함수에 전달되었지만 부모 함수 런타임의 중간에서 호출 된 경우 함수로 parent(cb) {dostuff1(); cb(); dostuff2()}간주되지 callback않습니까?
Max Yari

2
@ MaxYari : IMHO, 여전히 콜백으로 간주됩니다. 여기서 중요한 것은 부모 functin이 입력 함수 (일명 콜백)를 사용한다는 것입니다. 중간 또는 끝에서 또는 조건이 충족되는 경우 호출 할 수 있습니다.
Kamran Bigdely

12
@ 8bitjunkie 감사합니다-printANumber 함수 내에서 의미 OfLife 메소드는 어디에서 호출됩니까?
BKSpurgeon

2
"첫 번째 기능이 완료된 후 자동으로 호출됩니다." 콜백은 전혀 자동으로 수행 될 필요는 없습니다. 실제로 부모 함수가 완료되기 전에 콜백이 완료되는 것은 드문 일이 아닙니다. 나는 사람들이 콜백을 "나중에"실행되는 함수라고 묘사하는 것을 매우 싫어합니다. 그들에 대해 배우는 사람들에게는 매우 혼란 스럽습니다. 간단히 말해서 콜백은 다른 함수에 인수로 전달되는 함수일뿐입니다. 기간. 더 나은 설명에는 함수 참조에 대한 WHY 콜백 설명이 포함됩니다.
Jordan

225

불투명 정의

콜백 함수는 다른 코드에 제공하는 함수로, 해당 코드에서 호출 할 수 있습니다.

고안된 예

왜 이렇게 하시겠습니까? 호출해야 할 서비스가 있다고 가정 해 봅시다. 서비스가 즉시 반환되면 다음과 같습니다.

  1. 불러라
  2. 결과를 기다립니다
  3. 결과가 나오면 계속하십시오

예를 들어 서비스가 factorial기능 이라고 가정하십시오 . 의 값을 원하면 5!을 호출 factorial(5)하면 다음 단계가 수행됩니다.

  1. 현재 실행 위치가 스택에 저장되지만 중요하지는 않습니다.

  2. 사형 집행 factorial

  3. factorial완료, 그것은 결과를두고 어딘가에 당신은 그것을 얻을 수 있습니다

  4. 실행이 원래 있던 위치로 돌아옴 [1]

이제 factorial엄청난 수의 시간이 걸리고 일부 슈퍼 컴퓨팅 클러스터에서 실행해야하기 때문에 시간이 오래 걸린다고 가정하십시오. 결과를 반환하는 데 5 분이 걸릴 것으로 예상한다고 가정하겠습니다. 당신은 할 수 있습니다 :

  1. 잠을 잘 때 밤에 디자인을 유지하고 프로그램을 실행하여 화면을 절반 만 쳐다 보지 않도록하십시오.

  2. 동안 다른 일을 할 수있는 프로그램을 디자인 factorial의 일을하고

두 번째 옵션을 선택하면 콜백이 효과적 일 수 있습니다.

엔드 투 엔드 디자인

콜백 패턴을 이용 factorial하려면 다음과 같은 방법으로 전화를 걸 수 있습니다 .

factorial(really_big_number, what_to_do_with_the_result)

두 번째 매개 변수는, what_to_do_with_the_result당신이에 따라 전송하는 기능입니다 factorial희망, factorial반환하기 전에 그 결과를 호출합니다.

예, 이는 factorial콜백을 지원하기 위해 작성되어야 함을 의미합니다 .

이제 콜백에 매개 변수를 전달할 수 있다고 가정하십시오. 지금 당신은 그것을 부르지 않을 것이기 때문에 할 수 없습니다 factorial. 따라서 factorial매개 변수를 전달할 수 있도록 작성해야하며 호출 할 때 콜백에 전달합니다. 다음과 같이 보일 수 있습니다 :

factorial (number, callback, params)
{
    result = number!   // i can make up operators in my pseudocode
    callback (result, params)
}

이제이 factorial패턴 을 사용할 수 있습니다. 콜백은 다음과 같습니다.

logIt (number, logger)
{
    logger.log(number)
}

당신의 전화 factorial

factorial(42, logIt, logger)

무언가를 반품하려면 어떻게해야 logIt합니까? 글쎄, 당신은 factorial그것에주의를 기울이지 않기 때문에 할 수 없습니다 .

factorial콜백이 반환하는 것을 반환 할 수없는 이유는 무엇입니까?

비 차단 만들기

실행이 factorial끝나면 콜백으로 실행이 전달 되므로 실제로 호출자에게 아무것도 반환해서는 안됩니다. 이상적으로는 다른 스레드 / 프로세스 / 기계에서 작업을 시작하고 즉시 돌아와서 계속해서 다음과 같이 할 수 있습니다.

factorial(param_1, param_2, ...)
{
    new factorial_worker_task(param_1, param_2, ...);
    return;
}

이것은 이제 "비동기식 호출"입니다. 즉, 호출하면 즉시 반환되지만 실제로는 아직 수행되지 않은 것입니다. 따라서이를 확인하고 완료시 결과를 얻기위한 메커니즘이 필요하며 프로그램이 프로세스에서 더욱 복잡해졌습니다.

그리고이 패턴을 사용하면 factorial_worker_task콜백을 비동기 적으로 시작하고 즉시 돌아올 수 있습니다.

그래서 당신은 무엇을합니까?

답은 콜백 패턴 내에서 유지하는 것입니다. 쓸 때마다

a = f()
g(a)

그리고 f대신 쓸 것, 비동기 적으로 호출 할 수있다

f(g)

여기서 g콜백으로 전달됩니다.

이것은 기본적으로 프로그램의 흐름 토폴로지를 변경하며 익숙해지기까지합니다.

프로그래밍 언어는 함수를 즉석에서 생성 할 수있는 방법을 제공함으로써 많은 도움을 줄 수 있습니다. 바로 위의 코드에서 함수 g는만큼 작을 수 있습니다 print (2*a+1). 당신의 언어가 이것을 완전히 불필요한 이름과 서명을 가진 별도의 함수로 정의 할 것을 요구한다면,이 패턴을 많이 사용한다면 당신의 인생은 불쾌해질 것입니다.

반면에, 당신이 언어로 람다를 만들 수 있다면, 당신은 훨씬 더 나은 몸매를 가지게됩니다. 그런 다음 다음과 같은 것을 작성하게됩니다.

f( func(a) { print(2*a+1); })

훨씬 더 좋습니다.

콜백을 전달하는 방법

콜백 함수를 factorial어떻게 전달 합니까? 글쎄, 당신은 여러 가지 방법으로 그것을 할 수 있습니다.

  1. 호출 된 함수가 동일한 프로세스에서 실행중인 경우 함수 포인터를 전달할 수 있습니다.

  2. 또는 fn name --> fn ptr프로그램에서 사전을 유지하고 싶을 수도 있습니다 .이 경우 이름을 전달할 수 있습니다

  3. 어쩌면 당신의 언어로 람다로 가능한 함수를 제자리에서 정의 할 수 있습니다! 내부적으로는 일종의 객체를 만들고 포인터를 전달하지만 걱정할 필요는 없습니다.

  4. 아마도 호출하는 기능이 완전히 별도의 시스템에서 실행 중이며 HTTP와 같은 네트워크 프로토콜을 사용하여 호출하는 것일 수 있습니다. 콜백을 HTTP 호출 가능 함수로 노출하고 해당 URL을 전달할 수 있습니다.

당신은 아이디어를 얻습니다.

최근 콜백 증가

우리가 시작한이 웹 시대에서 우리가 호출하는 서비스는 종종 네트워크를 통해 이루어집니다. 우리는 종종 그러한 서비스에 대한 통제권을 가지고 있지 않습니다. 즉, 우리는 서비스를 작성하지 않았으며 유지 보수하지 않으며 서비스가 제대로 작동하는지 또는 수행 중인지 확인할 수 없습니다.

그러나 이러한 서비스가 응답하기를 기다리는 동안 프로그램이 차단 될 것으로 기대할 수 없습니다. 이를 알기 때문에 서비스 제공 업체는 종종 콜백 패턴을 사용하여 API를 설계합니다.

JavaScript는 람다 및 클로저와 같은 콜백을 매우 훌륭하게 지원합니다. 그리고 JavaScript 세계에서는 브라우저뿐만 아니라 서버에서도 많은 활동이 있습니다. 모바일 용으로 개발 된 JavaScript 플랫폼도 있습니다.

앞으로 나아갈수록 점점 더 많은 사람들이 비동기 코드를 작성하게 될 것이며,이 이해가 필수적입니다.


1
잘 설명 된 개념 ..! :)
piyushGoyal

좋은 설명, +1
Lingamurthy CS

1
이것은 다른 모든 사람들에게 가장 좋은 대답입니다. 친절하게 공감하십시오.
Abhishek Nalin

3
완벽하게 설명하고 모든 것이 설명됩니다. 다시 투표 할 수 있으면 좋겠습니다.
요게 쉬 야다 브

네, 자바 스크립트와 루비에서 lambas가 어떻게 작동하는지 이해합니다. 그리고 Java 8이지만 이전 버전의 Java는 lambas를 사용하지 않고 클래스를 대신 사용했으며 콜백이 어떻게 작동하는지 알고 싶습니다. 여전히 다른쪽에 대한 우수한 답변입니다.
도나 토

97

콜백은 한 단어입니다.

위키 백과 콜백 페이지에서 잘 설명합니다.

위키피디아 페이지에서 인용 :

컴퓨터 프로그래밍에서 콜백은 실행 코드 또는 실행 코드에 대한 참조로서 다른 코드에 대한 인수로 전달됩니다. 이것은 하위 레벨 소프트웨어 계층이 상위 레벨 계층에 정의 된 서브 루틴 (또는 기능)을 호출 할 수있게합니다.


14
답을 제시하는 좋은 방법.
Chathuranga Chandrasekara

1
그리고 이것은 또한 다른 방식으로 답을 이끌어냅니다. 명사 "콜백"은 "다시 호출"된 것으로, 종료를 통해 진행된 항목이 종료되고 로그인에 사용 된 것이 로그인과 같은 방식입니다.
익명

22
이것은 주석 일 수 있습니다-기본적으로 그것은 Wikipedia에 대한 링크입니다
CodyBugstein

Wikipedia는 실제로 멋진 프로그램을 가지고 있습니다. 나는 항상 "콜백"이라는 용어가 "나는 다시 전화 할 것이다 ..."라는 문구를 사용하여 가장 잘 설명 된 것처럼 느꼈습니다.
Thomas

javascriptissexy.com/에서 훌륭한 설명; 여기에 다시 게시하겠습니다. 콜백 함수는 다른 함수에 매개 변수로 전달되는 함수이며 다른 함수 내에서 콜백 함수가 호출되거나 실행됩니다. // click 메서드 매개 변수의 항목은 변수가 아니라 함수입니다 .// 항목은 콜백 함수입니다. $ ( "# btn_1"). click (function () {alert ( "Btn 1 Clicked" );}); 앞의 예에서 볼 수 있듯이 함수를 클릭 메서드에 매개 변수로 전달하여 함수를 실행합니다. –
MarcoZen

46

평신도의 반응은 특정 이벤트가 발생한 후 또는 일부 코드가 처리 된 후에 사용자가 아니라 사용자 또는 브라우저가 호출하는 함수라는 것입니다.


42

콜백 함수는 특정 조건이 충족 될 때 호출되어야하는 함수입니다. 콜백 함수는 즉시 호출되는 대신 특정 시점에 호출됩니다.

일반적으로 작업이 시작될 때 비동기 적으로 완료되는 경우에 사용됩니다 (예 : 호출 기능이 반환 된 후 얼마 후에 종료 됨).

예를 들어, 웹 페이지를 요청하는 함수는 호출자가 웹 페이지 다운로드가 완료되면 호출되는 콜백 함수를 제공하도록 요구할 수 있습니다.


첫 번째 문장 "...when a condition is met"에서 부모 함수가 실행을 끝내고 조건 (?)에 의존하지 않으면 콜백이 호출된다고 생각합니다.
Ojonugwa Jude Ochalifu

'확실한 조건'은 일반적으로 무작위가 아닌 이유 때문에 부름을 받는다는 의미입니다. 부모 / 생성자가 여전히 실행 중일 때 콜백이 호출 될 수 있습니다. 프로그래머가 예상하지 않으면 경쟁 조건이 발생할 수 있습니다.
Thomas Bratt


34

콜백은 전화 시스템 측면에서 가장 쉽게 설명됩니다. 함수 호출은 전화로 누군가에게 전화를 걸어 질문을하고, 답변을 얻고, 전화를 끊는 것과 유사합니다. 콜백을 추가하면 유추가 바뀌어 질문을 한 후 이름과 번호도 알려주므로 답변을 통해 다시 전화를 걸 수 있습니다.

-Paul Jakubik, "C ++의 콜백 구현"


1
내 이름과 번호는 함수입니까?
Koray Tugay

"콜백"이 그 대신에 좋은 이름 인 경우에는 유추 할 수 있습니다. 전화 교환 원에게 전화를 걸도록 요청합니다. 끝.
gherson

33

나는이 "콜백"전문 용어가 많은 곳에서 잘못 사용되었다고 생각합니다. 내 정의는 다음과 같습니다.

콜백 함수는 누군가에게 전달하여 특정 시점에 호출하도록하는 함수입니다.

사람들이 위키 정의의 첫 문장을 읽은 것 같습니다.

콜백은 실행 코드 또는 실행 코드에 대한 참조로서 다른 코드에 대한 인수로 전달됩니다.

나는 많은 API로 작업 해 왔으며 다양한 나쁜 예를 참조하십시오. 많은 사람들이 함수 포인터 (실행 코드에 대한 참조) 또는 익명 함수 (실행 코드)를 "콜백"이라고 부르는 경향이 있습니다. 단지 함수일 경우 다른 이름이 필요한 이유는 무엇입니까?

실제로 위키 정의의 두 번째 문장 만 콜백 함수와 일반 함수의 차이점을 나타냅니다.

이것은 하위 레벨 소프트웨어 계층이 상위 레벨 계층에 정의 된 서브 루틴 (또는 기능)을 호출 할 수있게합니다.

차이점은 함수를 전달할 사람과 전달 된 함수를 호출하는 방법입니다. 함수를 정의하고 다른 함수에 전달하여 해당 함수 본문에서 직접 호출 한 경우 콜백을 호출하지 마십시오. 정의는 전달 된 함수가 "하위 레벨"함수에 의해 호출 될 것이라고 말합니다.

사람들이 모호한 맥락에서이 단어의 사용을 중단 할 수 있기를 바랍니다.


2
당신의 대답은 말이 되겠지만 ... 나는 그것을 이해하는데 어려움을 겪고있다. 예를 들어 줄 수 있습니까?
CodyBugstein

3
@Zane Wong :: 마지막으로 "정의에 전달 된 함수는"하위 레벨 "함수에 의해 호출 될 것입니다." 하위 기능이 무엇을 나타내는 지 설명해 주시겠습니까? 예를 들면 더 좋습니다.
Viku

좋은 예일 것입니다
Yousuf Azad

1
고전적인 함수 호출과 콜백 스타일의 차이점은 의존적 인 방향과 관련이 있다고 생각합니다. 모듈 A가 모듈 B에 의존하고 ( "사용") A가 B의 함수를 호출하면 콜백이 아닙니다. A가 자신의 함수에 대한 참조를 B에 전달하면 B는 A의 함수를 호출합니다. 이것은 콜백입니다. 호출은 모듈 종속성과 비교하여 거꾸로 진행됩니다.
XouDo

30

간단하게 유지합시다. 콜백 기능이란 무엇입니까?

비유와 비유의 예

비서가 있습니다. 매일 나는 그녀에게 다음과 같이 요청한다 : (i) 우체국에서 회사의 발신 우편물을 버리고, 그녀가 그렇게 한 후에 : (ii) 내가 그 스티커 메모 중 하나에 대해 그녀에게 쓴 모든 일 .

이제 스티커 메모의 작업은 무엇입니까? 작업은 매일 다릅니다.

이 특정한 날에 그녀가 일부 문서를 인쇄하도록 요구한다고 가정하십시오. 스티커 메모에 메모를 적고 게시해야 할 발신 메일과 함께 책상에 고정합니다.

요약하자면:

  1. 먼저, 그녀는 우편물을 내려 놓고
  2. 작업이 완료된 직후에는 일부 문서를 인쇄해야합니다.

콜백 기능은 두 번째 작업입니다. 해당 문서를 인쇄하는 것입니다. 메일이 발송 된 후 완료되기 때문에, 그리고 문서를 인쇄하라는 스티커 메모가 게시해야 할 메일과 함께 제공됩니다.

이것을 프로그래밍 어휘와 묶어 봅시다

  • 이 경우의 메소드 이름은 DropOffMail입니다.
  • 콜백 함수는 다음과 같습니다. PrintOffDocuments. PrintOffDocuments는 DropOffMail이 실행 된 후에 만 ​​비서가이를 수행하기를 원하기 때문에 콜백 함수입니다.
  • 따라서 "오프 : PrintOffDocuments를 DropOffMail 메서드에 대한"인수 "로 전달합니다. 이것은 중요한 사항입니다.

그게 다야. 더 이상 없습니다. 나는 그것이 당신을 위해 그것을 정리했으면 좋겠다. 그렇지 않은 경우 의견을 게시하고 명확히하기 위해 최선을 다할 것이다.


18

이렇게하면 메소드 끝에서 콜백이 리턴 문처럼 들립니다.

나는 그것이 그들이 무엇인지 잘 모르겠습니다.

콜백은 실제로 다른 함수가 호출되어 완료된 결과 함수에 대한 호출이라고 생각합니다.

또한 콜백은 일종의 "야!


1
콜백 대 반환 문에 대한 질문에 +1 나는 이것에 사로 잡혔고 나와 함께 일하는 많은 졸업생들이 있습니다.
8bitjunkie

2
좋은 답변-다른 답변들과 달리 이해하는 데 도움이되었습니다!
adaam

18

콜백 이란 무엇입니까 ?

  • 일반적으로 누군가가받은 전화를 반환하기 위해 전화를 걸었습니다.
  • 컴퓨팅에서 콜백 은 실행 코드로, 다른 코드에 인수로 전달됩니다. 함수가 작업을 수행하거나 일부 이벤트가 발생하면 함수가 콜백을 호출합니다 (따라서 이름을 호출 함).

콜백 함수 란 무엇입니까 ?

  • 콜백 함수는 작업을 완료했을 때 마스터에게 "콜백"하는 하인과 같습니다.
  • 콜백 함수 (의이 다른 함수를 호출 할 수 있도록 다른 함수에 전달되는 함수 otherFunction매개 변수로)를하고, 콜백 함수 내에서 호출 (또는 실행)입니다 otherFunction.
    function action(x, y, callback) {
        return callback(x, y);
    }

    function multiplication(x, y) {
        return x * y;
    }

    function addition(x, y) {
        return x + y;
    }

    alert(action(10, 10, multiplication)); // output: 100

    alert(action(10, 10, addition)); // output: 20

SOA에서 콜백을 사용하면 플러그인 모듈이 컨테이너 / 환경에서 서비스에 액세스 할 수 있습니다.

유추 : 콜백. 비동기식. 콜백에 대한 비 차단
실제 예


콜백 함수 자체는 고차 함수가 아닙니다. 고차 함수에 전달됩니다.
danio

17

Call After 는 어리석은 이름 인 callback 보다 나은 이름 입니다. 함수 내에서 조건이 충족되면 호출 후 다른 함수를 호출하십시오. 인수로 수신 된 함수 인 합니다.

함수 내에서 내부 함수를 하드 코딩하는 대신 이미 작성된 Call After 함수를 인수 로 허용하는 함수를 작성 합니다. 후 전화 상태 변화에 따라 전화를받을 수있는 인수를 수신하는 기능의 코드에 의해 감지.


이것은 좋은 생각입니다. 나는 이것을 시도하고 설명하기 위해 "뒤로 전화했다"고 갔다. Martin Fowler와 같은 누군가가 그의 블로그에서 "call after"를 새로운 용어로 대중화하는 것을 볼 수있었습니다.
8bitjunkie

15

콜백 함수는 기존 함수 / 메소드에 지정하는 함수로, 작업이 완료되고 추가 처리가 필요할 때 호출됩니다.

예를 들어, 자바 스크립트 또는보다 구체적으로 jQuery에서는 애니메이션이 완료 될 때 호출 할 콜백 인수를 지정할 수 있습니다.

PHP에서 preg_replace_callback()함수를 사용하면 정규식이 일치 할 때 호출되는 함수를 제공 할 수 있으며, 일치하는 문자열을 인수로 전달할 수 있습니다.


10

이미지를보십시오 :)이것이 작동하는 방법입니다

기본 프로그램은 콜백 함수 이름으로 라이브러리 함수 (시스템 레벨 함수일 수도 있음)를 호출합니다. 이 콜백 함수는 여러 가지 방법으로 구현 될 수 있습니다. 기본 프로그램은 요구 사항에 따라 하나의 콜백을 선택합니다.

마지막으로 라이브러리 함수는 실행 중에 콜백 함수를 호출합니다.


7
이것에 텍스트 설명을 추가 하시겠습니까 ? 이미지가 사라지면이 답변은 모든 컨텍스트를 잃습니다.
Tim Post

다른 사람들의 텍스트가 그것을 가장 잘 설명해줍니다. 내가 느꼈던 유일한 것은 이미지입니다 :)

제가 여기에서 보았던 모든 긴 설명 중에서이 것은 "아 아아아, 이제는 그것의 사용을 본"것입니다. 공감하십시오.
DiBosco

7

이 질문에 대한 간단한 대답은 콜백 함수가 함수 포인터를 통해 호출되는 함수라는 것입니다. 함수의 포인터 (주소)를 다른 인수에 대한 인수로 전달하면 해당 포인터를 사용하여 함수를 호출 할 때 해당 함수가 가리키는 것이 다시 호출된다고 말합니다.


7

sort(int *arraytobesorted,void (*algorithmchosen)(void))구현할 때 사용할 수있는 함수 포인터를 인수로 받아 들일 수 있는 함수가 있다고 가정하자 sort(). 그런 다음 함수 포인터로 처리되는 코드를 콜백 함수algorithmchosen 라고 합니다. .

장점은 다음과 같은 알고리즘을 선택할 수 있다는 것입니다.

  1.    algorithmchosen = bubblesort
  2.    algorithmchosen = heapsort
  3.    algorithmchosen = mergesort   ...

예를 들어 프로토 타입으로 구현되었습니다.

  1.   `void bubblesort(void)`
  2.   `void heapsort(void)`
  3.   `void mergesort(void)`   ...

이것은 객체 지향 프로그래밍에서 다형성을 달성하는 데 사용되는 개념입니다


javascriptissexy.com/에서 훌륭한 설명; 여기서 다시 게시하겠습니다. 콜백 함수는 다른 함수에 매개 변수로 전달되는 함수이며 다른 함수 내에서 콜백 함수가 호출되거나 실행됩니다. // click 메서드 매개 변수의 항목은 변수가 아니라 함수입니다 .// 항목은 콜백 함수입니다. $ ( "# btn_1"). click (function () {alert ( "Btn 1 Clicked" );}); 앞의 예에서 볼 수 있듯이 함수를 클릭 메서드에 매개 변수로 전달하여 함수를 실행합니다. –
MarcoZen

4

“컴퓨터 프로그래밍에서 콜백은 실행 코드 또는 실행 코드에 대한 참조로 다른 코드에 대한 인수로 전달됩니다. 이를 통해 하위 레벨 소프트웨어 계층이 상위 레벨 계층에 정의 된 서브 루틴 (또는 기능)을 호출 할 수 있습니다.” -위키 백과

함수 포인터를 사용하여 C에서 콜백

C에서는 콜백이 함수 포인터를 사용하여 구현됩니다. 함수 포인터-이름에서 알 수 있듯이 함수에 대한 포인터입니다.

예를 들어, int (* ptrFunc) ();

여기서 ptrFunc는 인수를 사용하지 않고 정수를 반환하는 함수에 대한 포인터입니다. 괄호 안에 넣는 것을 잊지 마십시오. 그렇지 않으면 컴파일러는 ptrFunc가 일반 함수 이름이라고 가정합니다.이 함수는 아무것도 취하지 않고 정수에 대한 포인터를 반환합니다.

다음은 함수 포인터를 보여주는 코드입니다.

#include<stdio.h>
int func(int, int);
int main(void)
{
    int result1,result2;
    /* declaring a pointer to a function which takes
       two int arguments and returns an integer as result */
    int (*ptrFunc)(int,int);

    /* assigning ptrFunc to func's address */                    
    ptrFunc=func;

    /* calling func() through explicit dereference */
    result1 = (*ptrFunc)(10,20);

    /* calling func() through implicit dereference */        
    result2 = ptrFunc(10,20);            
    printf("result1 = %d result2 = %d\n",result1,result2);
    return 0;
}

int func(int x, int y)
{
    return x+y;
}

이제 함수 포인터를 사용하여 C에서 콜백의 개념을 이해하려고합니다.

완전한 프로그램에는 callback.c, reg_callback.h 및 reg_callback.c의 세 파일이 있습니다.

/* callback.c */
#include<stdio.h>
#include"reg_callback.h"

/* callback function definition goes here */
void my_callback(void)
{
    printf("inside my_callback\n");
}

int main(void)
{
    /* initialize function pointer to
    my_callback */
    callback ptr_my_callback=my_callback;                        
    printf("This is a program demonstrating function callback\n");
    /* register our callback function */
    register_callback(ptr_my_callback);                          
    printf("back inside main program\n");
    return 0;
}

/* reg_callback.h */
typedef void (*callback)(void);
void register_callback(callback ptr_reg_callback);


/* reg_callback.c */
#include<stdio.h>
#include"reg_callback.h"

/* registration goes here */
void register_callback(callback ptr_reg_callback)
{
    printf("inside register_callback\n");
    /* calling our callback function my_callback */
    (*ptr_reg_callback)();                               
}

이 프로그램을 실행하면 출력은

이것은 메인 프로그램 내에서 my_callback 내부의 register_callback 내에서 함수 콜백을 보여주는 프로그램입니다.

상위 계층 함수는 일반 호출로 하위 계층 함수를 호출하고 콜백 메커니즘을 통해 하위 계층 함수는 콜백 함수에 대한 포인터를 통해 상위 계층 함수를 호출 할 수 있습니다.

인터페이스를 사용한 자바 콜백

Java에는 함수 포인터 개념이 없습니다. 인터페이스 메커니즘을 통해 콜백 메커니즘을 구현합니다. 여기에서 함수 포인터 대신에 수신자가 작업을 완료 할 때 호출 될 메소드가있는 인터페이스를 선언합니다.

예제를 통해 보여 드리겠습니다.

콜백 인터페이스

public interface Callback
{
    public void notify(Result result);
}

발신자 또는 상위 레벨 클래스

public Class Caller implements Callback
{
Callee ce = new Callee(this); //pass self to the callee

//Other functionality
//Call the Asynctask
ce.doAsynctask();

public void notify(Result result){
//Got the result after the callee has finished the task
//Can do whatever i want with the result
}
}

수신자 또는 하위 계층 기능

public Class Callee {
Callback cb;
Callee(Callback cb){
this.cb = cb;
}

doAsynctask(){
//do the long running task
//get the result
cb.notify(result);//after the task is completed, notify the caller
}
}

EventListener 패턴을 사용한 콜백

  • 목록 항목

이 패턴은 특정 작업이 완료되었음을 0 ~ n 개의 관찰자 / 리스너에게 알리는 데 사용됩니다.

  • 목록 항목

콜백 메커니즘과 EventListener / Observer 메커니즘의 차이점은 콜백에서는 수신자가 단일 발신자에게 알리는 반면 Eventlisener / Observer에서는 수신자가 해당 이벤트에 관심이있는 사람에게 통지 할 수 있다는 것입니다 (알림은 작업을 트리거하지 않은 응용 프로그램)

예를 통해 설명하겠습니다.

이벤트 인터페이스

public interface Events {

public void clickEvent();
public void longClickEvent();
}

수업 위젯

package com.som_itsolutions.training.java.exampleeventlistener;

import java.util.ArrayList;
import java.util.Iterator;

public class Widget implements Events{

    ArrayList<OnClickEventListener> mClickEventListener = new ArrayList<OnClickEventListener>(); 
    ArrayList<OnLongClickEventListener> mLongClickEventListener = new ArrayList<OnLongClickEventListener>();

    @Override
    public void clickEvent() {
        // TODO Auto-generated method stub
        Iterator<OnClickEventListener> it = mClickEventListener.iterator();
                while(it.hasNext()){
                    OnClickEventListener li = it.next();
                    li.onClick(this);
                }   
    }
    @Override
    public void longClickEvent() {
        // TODO Auto-generated method stub
        Iterator<OnLongClickEventListener> it = mLongClickEventListener.iterator();
        while(it.hasNext()){
            OnLongClickEventListener li = it.next();
            li.onLongClick(this);
        }

    }

    public interface OnClickEventListener
    {
        public void onClick (Widget source);
    }

    public interface OnLongClickEventListener
    {
        public void onLongClick (Widget source);
    }

    public void setOnClickEventListner(OnClickEventListener li){
        mClickEventListener.add(li);
    }
    public void setOnLongClickEventListner(OnLongClickEventListener li){
        mLongClickEventListener.add(li);
    }
}

수업 버튼

public class Button extends Widget{
private String mButtonText;
public Button (){
} 
public String getButtonText() {
return mButtonText;
}
public void setButtonText(String buttonText) {
this.mButtonText = buttonText;
}
}

클래스 체크 박스

public class CheckBox extends Widget{
private boolean checked;
public CheckBox() {
checked = false;
}
public boolean isChecked(){
return (checked == true);
}
public void setCheck(boolean checked){
this.checked = checked;
}
}

활동 클래스

패키지 com.som_itsolutions.training.java.exampleeventlistener;

public class Activity implements Widget.OnClickEventListener
{
    public Button mButton;
    public CheckBox mCheckBox;
    private static Activity mActivityHandler;
    public static Activity getActivityHandle(){
        return mActivityHandler;
    }
    public Activity ()
    {
        mActivityHandler = this;
        mButton = new Button();
        mButton.setOnClickEventListner(this);
        mCheckBox = new CheckBox();
        mCheckBox.setOnClickEventListner(this);
        } 
    public void onClick (Widget source)
    {
        if(source == mButton){
            mButton.setButtonText("Thank you for clicking me...");
            System.out.println(((Button) mButton).getButtonText());
        }
        if(source == mCheckBox){
            if(mCheckBox.isChecked()==false){
                mCheckBox.setCheck(true);
                System.out.println("The checkbox is checked...");
            }
            else{
                mCheckBox.setCheck(false);
                System.out.println("The checkbox is not checked...");
            }       
        }
    }
    public void doSomeWork(Widget source){
        source.clickEvent();
    }   
}

다른 클래스

public class OtherClass implements Widget.OnClickEventListener{
Button mButton;
public OtherClass(){
mButton = Activity.getActivityHandle().mButton;
mButton.setOnClickEventListner(this);//interested in the click event                        //of the button
}
@Override
public void onClick(Widget source) {
if(source == mButton){
System.out.println("Other Class has also received the event notification...");
}
}

메인 클래스

public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Activity a = new Activity();
OtherClass o = new OtherClass();
a.doSomeWork(a.mButton);
a.doSomeWork(a.mCheckBox);
}
}

위의 코드에서 볼 수 있듯이 기본적으로 응용 프로그램에서 발생할 수있는 모든 이벤트를 나열하는 이벤트라는 인터페이스가 있습니다. Widget 클래스는 Button, Checkbox와 같은 모든 UI 구성 요소의 기본 클래스입니다. 이러한 UI 구성 요소는 실제로 프레임 워크 코드에서 이벤트를받는 객체입니다. Widget 클래스는 Events 인터페이스를 구현하며 OnClickEventListener 및 OnLongClickEventListener라는 두 개의 중첩 된 인터페이스를 가지고 있습니다.

이 두 인터페이스는 Button 또는 Checkbox와 같은 위젯 파생 UI 구성 요소에서 발생할 수있는 이벤트를 수신합니다. 따라서이 예제를 Java 인터페이스를 사용하는 이전 콜백 예제와 비교하면이 두 인터페이스가 콜백 인터페이스로 작동합니다. 따라서 상위 레벨 코드 (여기 활동)는이 두 인터페이스를 구현합니다. 그리고 이벤트가 위젯에 발생할 때마다 상위 레벨 코드 (또는 상위 레벨 코드로 구현 된 이러한 인터페이스의 메소드 (여기서는 Activity))가 호출됩니다.

이제 콜백과 이벤트 리스너 패턴의 기본적인 차이점에 대해 설명하겠습니다. 콜백을 사용하면 수신자는 단일 발신자에게만 알릴 수 있습니다. 그러나 EventListener 패턴의 경우 응용 프로그램의 다른 부분이나 클래스는 단추 또는 확인란에서 발생할 수있는 이벤트를 등록 할 수 있습니다. 이런 종류의 클래스의 예는 OtherClass입니다. OtherClass의 코드가 표시되면 Activity에 정의 된 Button에서 발생할 수있는 ClickEvent에 대한 리스너로 등록 된 것입니다. 흥미로운 부분은 액티비티 (발신자) 외에 버튼에서 클릭 이벤트가 발생할 때마다이 OtherClass에 통지된다는 것입니다.


제발 피하기 링크는 대답 . "외부 사이트로 연결되는 링크 이상"인 답변은 삭제 될 수 있습니다 .
Quentin

3

콜백 함수는 참조 나 포인터로 특정 함수 나 객체에 전달하는 함수입니다. 이 함수 또는 객체는 나중에 어떤 목적 으로든이 함수를 나중에 여러 번 다시 호출합니다.

  • 작업 종료 알림
  • c qsort ()와 같이 두 항목 간의 비교 요청
  • 프로세스 진행 상황보고
  • 이벤트 알림
  • 개체의 인스턴스 위임
  • 지역의 그림을 위임

...

따라서 콜백을 다른 함수 또는 작업이 끝날 때 호출되는 함수로 설명하면 (일반적인 사용 사례 일지라도) 지나치게 단순화됩니다.


2

콜백은 함수를 매개 변수로 함수를 다른 함수에 전달하고 프로세스가 완료되면이를 호출하는 아이디어입니다.

위의 멋진 답변을 통해 콜백 개념을 얻는다면 아이디어의 배경을 배우는 것이 좋습니다.

"그들 (컴퓨터 과학자들)이 콜백을 개발하게 한 이유는 무엇입니까?" 차단하는 문제를 배울 수 있습니다. (특히 UI 차단) 콜백이 유일한 해결책은 아닙니다. 다른 솔루션이 많이 있습니다 (예 : Thread, Futures, Promises ...).


1

중요한 사용 영역 중 하나는 함수 중 하나를 핸들 (예 : 콜백)로 등록한 다음 메시지를 보내거나 함수를 호출하여 일부 작업 또는 처리를 수행하는 것입니다. 이제 처리가 완료된 후 호출 된 함수는 등록 된 함수를 호출하여 (즉, 콜백이 완료 됨) 처리가 완료되었음을 나타냅니다.
위키 백과 링크는 그래픽으로 잘 설명되어 있습니다.


1

고차 함수라고도하는 콜백 함수는 매개 변수로 다른 함수에 전달되는 함수이며, 부모 함수 내에서 콜백 함수가 호출 (또는 실행)됩니다.

$("#button_1").click(function() {
  alert("button 1 Clicked");
});

여기에 click 메소드에 매개 변수로 함수를 전달했습니다. 그리고 click 메소드는 전달 된 콜백 함수를 호출 (또는 실행)합니다.


1
콜백 함수 자체는 고차 함수가 아닙니다. 고차 함수에 전달됩니다.
danio

1

콜백 함수 다른 함수에 인수로 전달 된 함수입니다.

function test_function(){       
 alert("Hello world");  
} 

setTimeout(test_function, 2000);

참고 : 위 예제에서 test_function은 setTimeout 함수의 인수로 사용되었습니다.


1
스택 오버플로에 오신 것을 환영합니다! 질문에 대답하기 전에 항상 기존 답변을 읽으십시오. 이 답변은 이미 제공되었습니다. 답변을 반복하지 말고 기존 답변에 투표하십시오. 좋은 답변을 작성하기위한 몇 가지 지침은 여기 에서 찾을 수 있습니다 .
dferenc
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.