如何用纯英文解释callback? 它们与另一个函数调用一个函数有什么不同?

如何用简单的英文解释callback? 它们与从另一个函数中调用一个函数的方式有什么区别? 他们的权力如何向新手程序员解释?

通常,应用程序需要根据上下文/状态执行不同的function。 为此,我们使用一个variables来存储关于被调用函数的信息。 根据它的需要,应用程序将设置这个variables与要调用的函数有关的信息,并将使用相同的variables调用该函数。

在JavaScript中,示例如下。 在这里我们使用方法参数作为variables来存储关于函数的信息。

function processArray(arr, callback) { var resultArr = new Array(); for (var i = arr.length-1; i >= 0; i--) resultArr[i] = callback(arr[i]); return resultArr; } var arr = [1, 2, 3, 4]; var arrReturned = processArray(arr, function(arg) {return arg * -1;}); // arrReturned would be [-1, -2, -3, -4] 

我将尽量保持这个简单。 “callback”是由第一个函数作为参数的另一个函数调用的任何函数。 很多时候,“callback”是一个事件发生时被调用的函数。 在程序员发言中,这可以被称为“事件”。

想象一下这个场景:你正在等待几天的时间。 这个包是你邻居的礼物。 因此,一旦你拿到包裹,就要把它带到邻居家。 你不在城里,所以你给你的配偶留下指示。

你可以告诉他们拿到包裹并把它带给邻居。 如果你的配偶和电脑一样愚蠢,他们会坐在门口等待包裹,直到它到来(不要别的),然后一旦到了,就把它带到邻居家。 但是有一个更好的方法。 告诉你的配偶,一旦他们收到包裹,他们应该把它交给邻居。 然后,他们可以正常的生活直到他们收到包裹。

在我们的例子中,包的接收是“事件”,把它带给邻居是“callback”。 您的配偶“运行”您的指示,只有包裹到达才能将包裹带走。 好多了!

这种思维在日常生活中是显而易见的,但电脑并不具备同样的常识。 考虑程序员通常如何写入一个文件:

 fileObject = open(file) # now that we have WAITED for the file to open, we can write to it fileObject.write("We are writing to the file.") # now we can continue doing the other, totally unrelated things our program does 

在这里,我们等待文件打开,然后再写入它。 这“阻塞”了执行的stream程,我们的程序不能做任何可能需要做的事情! 如果我们能做到这一点,会怎样呢?

 # we pass writeToFile (A CALLBACK FUNCTION!) to the open function fileObject = open(file, writeToFile) # execution continues flowing -- we don't wait for the file to be opened # ONCE the file is opened we write to it, but while we wait WE CAN DO OTHER THINGS! 

事实certificate,我们用一些语言和框架来做到这一点。 这很酷! 查看Node.js ,通过这种思考来获得一些真正的实践。

如何用简单的英文解释callback?

用简单的英语,callback函数就像一个工作人员在完成一个任务时“回叫”他的经理

它们与从另一个函数中调用一个函数的方式有什么区别?

确实是从另一个函数调用一个函数,但关键是callback被看作是一个Object,所以你可以根据系统的状态(比如Strategy Design Pattern)改变调用哪个函数。

他们的权力如何向新手程序员解释?

callback的力量很容易在AJAX式的网站上看到,这些网站需要从服务器上获取数据。 下载新的数据可能需要一些时间。 如果没有callback,整个用户界面在下载新数据时会“冻结”,或者需要刷新整个页面,而不是整个页面的一部分。 通过callback,您可以插入一个“正在加载”的图像,并在加载后用新数据replace它。

一些没有callback的代码:

 function grabAndFreeze() { showNowLoading(true); var jsondata = getData('http://yourserver.com/data/messages.json'); /* User Interface 'freezes' while getting data */ processData(jsondata); showNowLoading(false); do_other_stuff(); // not called until data fully downloaded } function processData(jsondata) { // do something with the data var count = jsondata.results ? jsondata.results.length : 0; $('#counter_messages').text(['Fetched', count, 'new items'].join(' ')); $('#results_messages').html(jsondata.results || '(no new messages)'); } 

随着callback:

下面是一个使用jQuery的getJSON进行callback的例子:

 function processDataCB(jsondata) { // callback: update UI with results showNowLoading(false); var count = jsondata.results ? jsondata.results.length : 0; $('#counter_messages').text(['Fetched', count, 'new items'].join(' ')); $('#results_messages').html(jsondata.results || '(no new messages)'); } function grabAndGo() { // and don't freeze showNowLoading(true); $('#results_messages').html(now_loading_image); $.getJSON("http://yourserver.com/data/messages.json", processDataCB); /* Call processDataCB when data is downloaded, no frozen User Interface! */ do_other_stuff(); // called immediately } 

closures:

callback通常需要使用closure来访问调用函数的state ,这就像工作人员在完成任务之前需要从Manager中获取信息一样。 要创buildclosure ,可以内联函数,以便在调用上下文中看到数据:

 /* Grab messages, chat users, etc by changing dtable. Run callback cb when done.*/ function grab(dtable, cb) { if (null == dtable) { dtable = "messages"; } var uiElem = "_" + dtable; showNowLoading(true, dtable); $('#results' + uiElem).html(now_loading_image); $.getJSON("http://yourserver.com/user/"+dtable+".json", cb || function (jsondata) { // Using a closure: can "see" dtable argument and uiElem variables above. var count = jsondata.results ? jsondata.results.length : 0, counterMsg = ['Fetched', count, 'new', dtable].join(' '), // no new chatters/messages/etc defaultResultsMsg = ['(no new ', dtable, ')'].join(''); showNowLoading(false, dtable); $('#counter' + uiElem).text(counterMsg); $('#results'+ uiElem).html(jsondata.results || defaultResultsMsg); }); /* User Interface calls cb when data is downloaded */ do_other_stuff(); // called immediately } 

用法:

 // update results_chatters when chatters.json data is downloaded: grab("chatters"); // update results_messages when messages.json data is downloaded grab("messages"); // call myCallback(jsondata) when "history.json" data is loaded: grab("history", myCallback); 

closures

最后,这是道格拉斯·克罗克福德关于closure的定义:

函数可以在其他函数中定义。 内部函数可以访问外部函数的variables和参数。 如果对内部函数的引用存活(例如,作为callback函数),则外部函数的variables也可以存活。

也可以看看:

我惊讶地发现许多聪明的人没有强调现实,“callback”这个词已经以两种不一致的方式被使用了。

这两种方式都涉及通过向现有函数传递附加function(函数定义,匿名或命名)来定制函数。 即。

 customizableFunc(customFunctionality) 

如果自定义function只是插入到代码块中,那么您已经自定义了function,就像这样。

  customizableFucn(customFunctionality) { var data = doSomthing(); customFunctionality(data); ... } 

虽然这种注入function通常被称为“callback”,但没有什么特别之处。 一个非常明显的例子是forEach方法,其中自定义函数作为参数提供给数组中的每个元素以修改数组。

但是,这与使用asynchronous编程的“callback”function(如AJAX或node.js)或简单地将function分配给用户交互事件(如鼠标点击)截然不同。 在这种情况下,整个想法是在执行自定义function之前等待一个或有事件发生。 这在用户交互的情况下是显而易见的,但是在I / O(input/输出)处理中也是重要的,这可能花费时间,例如从磁盘读取文件。 这就是“callback”这个词最为明显的地方。 一旦I / O进程启动(如要求从磁盘读取文件或从http请求返回数据的服务器) asynchronous程序不会等待完成。 它可以继续进行下一步计划的任何任务,只有在通知读取文件或http请求已完成(或失败)并且数据可用于自定义function后,才会使用自定义function进行响应。 就像在电话上打个电话,留下你的“回拨”号码,这样他们可以打电话给你,当有人可以找回你。 谁知道谁能知道这个问题有多久,不能参加其他事情呢?

asynchronous使用固有地涉及一些监听所需事件(例如,I / O过程的完成)的方法,以便当它发生时(并且仅当它发生时)执行定制的“callback”function。 在显而易见的AJAX示例中,当数据实际从服务器到达时,将触发“callback”函数,以使用该数据修改DOM,从而将浏览器窗口重新绘制到该范围。

回顾一下。 有些人使用“callback”这个词来指任何可以注入现有函数的自定义function作为参数。 但是,至less对我来说,这个词的最恰当的用法是注入的“callback”函数被asynchronous使用的地方 – 只有在等待被通知的事件发生时才被执行。

在非程序员的angular度来说,callback是一个程序中的空白。

许多纸质表格上的一个共同的项目是“紧急情况下打电话的人”。 那里有一个空白的行。 你写在别人的姓名和电话号码。 如果发生紧急情况,那么这个人就会被叫醒。

  • 每个人都有相同的空白表格,但是
  • 每个人都可以写一个不同的紧急联络电话

这是关键。 你不改变forms(代码,通常是别人的)。 但是你可以填写缺less的信息( 你的号码)。

例1:

callback被用作自定义的方法,可能用于添加/改变程序的行为。 例如,采取一些执行function的C代码,但不知道如何打印输出。 它只能做一个string。 当它试图找出如何处理string,它看到一个空白的行。 但是,程序员给了你空白来写你的callback!

在这个例子中,你不用一支铅笔来填写一张纸上的空白,你可以使用函数set_print_callback(the_callback)

  • 模块/代码中的空白variables是空白行,
  • set_print_callback是铅笔,
  • the_callback是你填写的信息。

您现在已经在程序中填入了这个空行。 无论何时需要打印输出,它都会查看空白行,然后按照说明进行操作(即调用放在其中的function)。实际上,这样可以打印到日志文件,打印机,通过networking连接,或其任何组合。 你已经填补了你想做什么的空白。

例2:

当你被告知需要拨打一个紧急电话号码时,你可以阅读纸质表格上的内容,然后拨打你所阅读的电话号码。 如果这条线是空白的,则不会做任何事情。

Gui编程的工作原理也是一样的。 当一个button被点击,程序需要找出接下来要做的事情。 它去,并寻找callback。 这个callback恰好在一个空白的标签上,“这就是你点击Button1时的操作”

大多数IDE会自动为你填写空白(写出基本的方法),当你问它(例如button1_clicked )。 然而,这个空白可以有任何方法,你请好 。 只要您将callback的名称放在适当的空白处,就可以调用方法run_computationsbutter_the_biscuits 。 你可以把“555-555-1212”放在紧急号码的空白处。 这没有什么意义,但这是可以的。


最后说明:你用callback填写的空白行? 可以随意擦除和重写。 (不pipe你是否应该是另一个问题,但这是他们权力的一部分)

Johny,程序员需要一个订书机,所以他到办公室供应部门,要求填写申请表格后,他可以站在那里等待办事人员去仓库找订书机(就像一个阻塞函数调用)或者去做别的事情。

由于这通常需要时间,johny会在请求表格中附上一张纸条,要求他们在订书机准备好取件时打电话给他,这样他就可以做一些其他的事情,比如在办公桌上打盹。

总是更好的开始一个例子:)。

假设你有两个模块A和B.

你希望模块A在模块B发生某些事件/情况时得到通知 。但是,模块B不知道你的模块A.它所知道的是一个通过函数指针指向特定函数(模块A)的地址由模块A提供给它

所以现在所有的B都必须这样做,当通过使用函数指针发生特定的事件/条件时,是对模块A的“callback”。 A可以在callback函数中做进一步的处理。

*)这里的一个明显的优点是,你正在从模块B抽象出关于模块A的所有内容。模块B不必关心谁是/什么模块A.

想象一下,你需要一个函数返回10平方,所以你写一个函数:

 function tenSquared() {return 10*10;} 

后来你需要9平方,所以你写另一个function:

 function nineSquared() {return 9*9;} 

最终你将用一个通用函数来replace所有这些:

 function square(x) {return x*x;} 

完全相同的思路适用于callback。 你有一个function,做一些事情,当完成调用doA:

 function computeA(){ ... doA(result); } 

后来你想要完全相同的函数来调用doB,而不是你可以复制整个函数:

 function computeB(){ ... doB(result); } 

或者你可以传递一个callback函数作为一个variables,只需要有一次的function:

 function compute(callback){ ... callback(result); } 

那么你只需要调用计算(doA)和计算(doB)。

除了简化代码之外,它还允许asynchronous代码通过在完成时调用任意函数来告诉您它已完成,类似于在电话上呼叫某人并留下回叫号码。

你感觉不舒服,所以你去看医生。 他检查你并确定你需要一些药物。 他开了一些药,然后把药方叫进当地的药房。 你回家。 稍后您的药房打电话告诉您您的处方已准备就绪。 你去捡起来。

有两点需要解释,一个是callback是如何工作的(传递一个可以在不知道其上下文的情况下调用的函数),另一个是它用于(asynchronous处理事件)的。

等待一个已经被其他答案使用的包裹的类比是一个很好的解释。 在计算机程序中,你会告诉计算机期待一个包裹。 通常情况下,它现在坐在那里,等待(直到包裹到达),如果没有到达,可能无限期地等待。 对于人类来说,这听起来很愚蠢,但是没有进一步的措施,这对于电脑来说是完全自然的。

现在callback将是你的前门的钟声。 您提供包裹服务的方式,通知您包裹到达,而不必知道您在哪里(即使)在房子里,或者如何响铃。 (例如,一些“钟声”实际上是在发送一个电话。)因为你提供了一个“callback函数”,在任何时候都可以被“呼叫”,不用说,你现在可以停下来坐在前廊,“处理事件“(包裹到达),无论何时。

想象一个朋友正在离开你的房子,你告诉她:“当你回家时给我打电话,以便我知道你已经平安到达了。 这是(字面上) 回电 。 这是一个callback函数,不pipe语言如何。 你需要一些程序在完成某个任务时将控制权交回给你,所以你给它一个函数用来回叫你。

在Python中,例如,

 grabDBValue( (lambda x: passValueToGUIWindow(x) )) 

grabDBValue可以写成只从数据库中获取一个值,然后让你指定实际的值,所以它接受一个函数。 你不知道什么时候或者如果grabDBValue会返回,但是如果/当它发生时,你知道你想要它做什么。 在这里,我传入一个匿名函数(或lambda ),将值发送到GUI窗口。 我可以很容易地通过这样做来改变程序的行为:

 grabDBValue( (lambda x: passToLogger(x) )) 

callback函数在函数是第一类值的语言中工作得很好,就像通常的整数,string,布尔值等一样。在C中,你可以通过传递一个指针来调用函数,调用者可以使用它。 在Java中,由于在类之外不存在函数(“方法”),因此调用者将要求具有特定方法名称的特定types的静态类; 而在大多数其他dynamic语言中,您只需使用简单的语法即可传递函数。

普罗蒂普:

在使用词法范围的语言(如Scheme或Perl)中,您可以像这样做:

 my $var = 2; my $val = someCallerBackFunction(sub callback { return $var * 3; }); # Perlistas note: I know the sub doesn't need a name, this is for illustration 

$val在这种情况下将是6因为callback可以访问在定义的词法环境中声明的variables。 词汇范围和匿名callback是一个强大的组合,需要新手程序员进一步学习。

你有一些你想运行的代码。 通常情况下,当你调用它的时候,你会在继续之前等待它完成(这会导致你的应用程序变灰/产生一个游标的旋转时间)。

另一种方法是并行运行这些代码,并继续进行自己的工作。 但是,如果您的原始代码需要根据所调用代码的响应做不同的事情呢? 那么,在这种情况下,您可以传递完成后要调用的代码的名称/位置。 这是“回电”。

正常代码:询问信息 – >处理信息 – >处理结果处理 – >继续做其他事情。

用callback:询问信息 – >处理信息 – >继续做其他事情。 并在稍后的一点 – >处理结果的处理。

如果没有其他特殊的编程资源(如线程和其他)没有callback, 程序就是一个接一个地按顺序执行的一系列指令 ,即使有一些由某些条件决定的“dynamic行为”, 所有可能的场景应预先编程

所以,如果我们需要提供一个真正的dynamic行为,我们可以使用callback。 通过callback,你可以通过参数来指示一个程序调用另外一个程序来提供一些以前定义的参数,并且可以期待一些结果( 这是合同或操作签名 ),所以这些结果可以由第三方程序生成/处理,以前不知道。

这种技术是应用于程序,函数,对象和所有其他计算机运行的代码的多态的基础。

当你做一些工作时,以人类世界为例来回答这个问题是很好的解释,让我们假设你是一个画家( 在这里你是主要的程序 ),有时候打电话给你的客户,要求他批准工作的结果,所以他决定图片是否好( 你的客户是第三方程序 )。

在上面的例子中,你是一个画家,为他人“委托”批准结果的工作,画面是参数,每个新的客户(被调用的“function”)改变你的工作结果,决定他想要什么关于图片( 客户端的决定是“callback函数”的返回结果 )。

我希望这个解释是有用的。

让我们假装你给我一个潜在的长期运行的任务:得到你遇到的前五个独特的人的名字。 如果我在人烟稀less的地区,这可能需要几天的时间。 在我四处奔波的时候,你并不是真的有兴趣坐在你的手上,所以你说:“当你有清单的时候,给我打电话,把它读回给我,这是数字。”

你已经给了我一个callback引用 – 一个函数,我应该执行,以便进一步处理。

在JavaScript中,它可能看起来像这样:

 var lottoNumbers = []; var callback = function(theNames) { for (var i=0; i<theNames.length; i++) { lottoNumbers.push(theNames[i].length); } }; db.executeQuery("SELECT name " + "FROM tblEveryOneInTheWholeWorld " + "ORDER BY proximity DESC " + "LIMIT 5", callback); while (lottoNumbers.length < 5) { playGolf(); } playLotto(lottoNumbers); 

这可能有很多方面可以改善。 例如,您可以提供第二个回叫:如果结束时间超过一个小时,请拨打红色电话,并告诉对方您已超时。

callback函数将被第二个函数调用。 第二个函数事先不知道它将调用什么函数。 所以callback函数的标识存储在某个地方,或作为parameter passing给第二个函数。 这个“身份”,取决于编程语言,可能是callback的地址,或者其他types的指针,或者它可能是函数的名字。 校长是一样的,我们存储或传递一些明确标识function的信息。

到时候,第二个函数可以调用callback函数,根据当时的情况提供参数。 它甚至可以从一组可能的callback中selectcallback。 编程语言必须提供某种语法来允许第二个函数调用callback,并知道它的“标识”。

这个机制有很多可能的用途。 通过callback,函数的devise者可以通过调用任何callback来定制它。 例如,sorting函数可能会将callback作为参数,这个callback函数可能是比较两个元素以决定哪一个先来的函数。

顺便说一下,依赖于编程语言,上述讨论中的“function”一词可以用“块”,“闭包”,“拉姆达”等代替。

在电话系统方面,回叫最容易描述。 函数调用就像在电话上打电话给某人,问她一个问题,得到一个答案,然后挂断电话。 添加一个callback改变了这个比喻,所以在问她一个问题之后,你还可以给她你的姓名和电话号码,这样她就可以给你回电话了。 – Paul Jakubik,“C ++中的callback实现”

一个隐喻的解释:

我有一个包裹要交给朋友,我也想知道我朋友什么时候收到的。

所以我把包裹送到邮局,要求他们提供。 如果我想知道我的朋友何时收到包裹,我有两个select:

(一)我可以在邮局等待,直到交付。

(b)交付时我会收到一封电子邮件。

选项(b)类似于callback。

为了教授callback,你必须先教导指针。 一旦学生理解了指向variables的想法,callback的想法将变得更加容易。 假设你正在使用C / C ++,可以遵循这些步骤。

  • 首先向学生展示如何使用指针并使用普通variables标识符来操作variables。
  • 然后教他们有些东西只能用指针来完成(像通过引用传递variables)。
  • 然后告诉他们可执行代码或函数如何像内存中的其他数据(或variables)一样。 所以,函数也有地址或指针。
  • 然后向他们展示如何用函数指针调用函数,并告诉它们被称为callback函数。
  • 现在的问题是,为什么所有这些调用一些函数的麻烦? 有什么好处? 像数据指针一样,函数指针akacallback比使用普通标识符有一些优点。
  • 第一个是function标识符或function名称不能用作普通数据。 我的意思是,你不能使用函数(如数组或函数的链表)来创build数据结构。 但是通过callback,你可以创build一个数组,一个链表,或者像键值对或树的字典中的其他数据一样使用它们,或者使用其他任何东西。 这是一个强大的好处。 而其他的好处其实是这个孩子。
  • 事件驱动程序编程中最常见的callback用法。 根据某个input信号执行一个或多个function。 通过callback,可以维护一个字典来映射带有callback的信号。 然后input信号分辨率和相应的代码执行变得更容易。
  • 我脑海中第二次使用callback是高阶函数。 将其他函数作为input参数的函数。 发送函数作为参数,我们需要callback。 一个例子可以是一个需要数组和callback的函数。 然后它对数组中的每个项目执行callback,并将结果返回到另一个数组中。 如果我们传递一个双倍的callback函数,我们得到一个doubled值的数组。 如果我们通过平方callback,我们得到正方形。 对于平方根,只需发送适当的callback。 这不能用正常的function来完成。

可能还有更多的东西。 让学生参与,他们会发现。 希望这可以帮助。

通常我们发送variables给函数。 假设你有任务需要在作为参数给出variables之前处理 – 你可以使用callback函数。

function1(var1, var2)是常用的方法。

如果我想要处理var2然后作为参数发送呢? function1(var1, function2(var2))

这是一种callback – 其中function2执行一些代码并返回一个variables回到初始函数。

In plain english a callback is a promise. Joe, Jane, David and Samantha share a carpool to work. Joe is driving today. Jane, David and Samantha have a couple of options:

  1. Check the window every 5 minutes to see if Joe is out
  2. Keep doing their thing until Joe rings the door bell.

Option 1: This is more like a polling example where Jane would be stuck in a "loop" checking if Joe is outside. Jane can't do anything else in the mean time.

Option 2: This is the callback example. Jane tells Joe to ring her doorbell when he's outside. She gives him a "function" to ring the door bell. Joe does not need to know how the door bell works or where it is, he just needs to call that function ie ring the door bell when he's there.

Callbacks are driven by "events". In this example the "event" is Joe's arrival. In Ajax for example events can be "success" or "failure" of the asynchronous request and each can have the same or different callbacks.

In terms of JavaScript applications and callbacks. We also need to understand "closures" and application context. What "this" refers to can easily confuse JavaScript developers. In this example within each person's "ring_the_door_bell()" method/callback there might be some other methods that each person need to do based on their morning routine ex. "turn_off_the_tv()". We would want "this" to refer to the "Jane" object or the "David" object so that each can setup whatever else they need done before Joe picks them up. This is where setting up the callback with Joe requires parodying the method so that "this" refers to the right object.

希望有所帮助!

A callback is a self-addressed stamped envelope. When you call a function, that is like sending a letter. If you want that function to call another function you provide that information in the form of a reference or address.

What Is a Callback Function?

The simple answer to this first question is that a callback function is a function that is called through a function pointer. If you pass the pointer (address) of a function as an argument to another, when that pointer is used to call the function it points to it is said that a call back is made.

Callback function is hard to trace, but sometimes it is very useful. Especially when you are designing libraries. Callback function is like asking your user to gives you a function name, and you will call that function under certain condition.

For example, you write a callback timer. It allows you to specified the duration and what function to call, and the function will be callback accordingly. “Run myfunction() every 10 seconds for 5 times”

Or you can create a function directory, passing a list of function name and ask the library to callback accordingly. “Callback success() if success, callback fail() if failed.”

Lets look at a simple function pointer example

 void cbfunc() { printf("called"); } int main () { /* function pointer */ void (*callback)(void); /* point to your callback function */ callback=(void *)cbfunc; /* perform callback */ callback(); return 0; } 

How to pass argument to callback function?

Observered that function pointer to implement callback takes in void *, which indicates that it can takes in any type of variable including structure. Therefore you can pass in multiple arguments by structure.

 typedef struct myst { int a; char b[10]; }myst; void cbfunc(myst *mt) { fprintf(stdout,"called %d %s.",mt->a,mt->b); } int main() { /* func pointer */ void (*callback)(void *); //param myst m; ma=10; strcpy(mb,"123"); callback = (void*)cbfunc; /* point to callback function */ callback(&m); /* perform callback and pass in the param */ return 0; } 

A callback is a method that is scheduled to be executed when a condition is met.

An "real world" example is a local video game store. You are waiting for Half-Life 3. Instead of going to the store every day to see if it is in, you register your email on a list to be notified when the game is available. The email becomes your "callback" and the condition to be met is the game's availability.

A "programmers" example is a web page where you want to perform an action when a button is clicked. You register a callback method for a button and continue doing other tasks. When/if the user cicks on the button, the browser will look at the list of callbacks for that event and call your method.

A callback is a way to handle events asynchronously. You can never know when the callback will be executed, or if it will be executed at all. The advantage is that it frees your program and CPU cycles to perform other tasks while waiting for the reply.

Plain and simple: A callback is a function that you give to another function, so that it can call it.

Usually it is called when some operation is completed. Since you create the callback before giving it to the other function, you can initialize it with context information from the call site. That is why it is named a call*back* – the first function calls back into the context from where it was called.

I think it's an rather easy task to explain.

At first callback are just ordinary functions.
And the further is, that we call this function (let's call it A) from inside another function (let's call it B).

The magic about this is that I decide, which function should be called by the function from outside B.

At the time I write the function BI don't know which callback function should be called. At the time I call function BI also tell this function to call function A. That is all.

“In computer programming, a callback is a reference to executable code, or a piece of executable code, that is passed as an argument to other code. This allows a lower-level software layer to call a subroutine (or function) defined in a higher-level layer.” – Wikipedia

Callback in C using Function Pointer

In C, callback is implemented using Function Pointer. Function Pointer – as the name suggests, is a pointer to a function.

For example, int (*ptrFunc) ();

Here, ptrFunc is a pointer to a function that takes no arguments and returns an integer. DO NOT forget to put in the parenthesis, otherwise the compiler will assume that ptrFunc is a normal function name, which takes nothing and returns a pointer to an integer.

Here is some code to demonstrate the function pointer.

 #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; } 

Now let us try to understand the concept of Callback in C using function pointer.

The complete program has three files: callback.c, reg_callback.h and 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)(); } 

If we run this program, the output will be

This is a program demonstrating function callback inside register_callback inside my_callback back inside main program

The higher layer function calls a lower layer function as a normal call and the callback mechanism allows the lower layer function to call the higher layer function through a pointer to a callback function.

Callback in Java Using Interface

Java does not have the concept of function pointer It implements Callback mechanism through its Interface mechanism Here instead of a function pointer, we declare an Interface having a method which will be called when the callee finishes its task

Let me demonstrate it through an example:

The Callback Interface

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

The Caller or the Higher Level Class

 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 } } 

The Callee or the lower layer function

 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 } } 

Callback Using EventListener pattern

  • 列表项目

This pattern is used to notify 0 to n numbers of Observers/Listeners that a particular task has finished

  • 列表项目

The difference between Callback mechanism and EventListener/Observer mechanism is that in callback, the callee notifies the single caller, whereas in Eventlisener/Observer, the callee can notify anyone who is interested in that event (the notification may go to some other parts of the application which has not triggered the task)

Let me explain it through an example.

The Event Interface

 public interface Events { public void clickEvent(); public void longClickEvent(); } 

Class Widget

 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); } } 

Class Button

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

Class Checkbox

 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; } } 

Activity Class

package 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(); } } 

Other Class

 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..."); } } 

Main Class

 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); } } 

As you can see from the above code, that we have an interface called events which basically lists all the events that may happen for our application. The Widget class is the base class for all the UI components like Button, Checkbox. These UI components are the objects that actually receive the events from the framework code. Widget class implements the Events interface and also it has two nested interfaces namely OnClickEventListener & OnLongClickEventListener

These two interfaces are responsible for listening to events that may occur on the Widget derived UI components like Button or Checkbox. So if we compare this example with the earlier Callback example using Java Interface, these two interfaces work as the Callback interface. So the higher level code (Here Activity) implements these two interfaces. And whenever an event occurs to a widget, the higher level code (or the method of these interfaces implemented in the higher level code, which is here Activity) will be called.

Now let me discuss the basic difference between Callback and Eventlistener pattern. As we have mentioned that using Callback, the Callee can notify only a single Caller. But in the case of EventListener pattern, any other part or class of the Application can register for the events that may occur on the Button or Checkbox. The example of this kind of class is the OtherClass. If you see the code of the OtherClass, you will find that it has registered itself as a listener to the ClickEvent that may occur in the Button defined in the Activity. Interesting part is that, besides the Activity ( the Caller), this OtherClass will also be notified whenever the click event occurs on the Button.

[edited]when we have two functions say functionA and functionB ,if functionA depends on functionB .

then we call functionB as a callback function .this is widely used in Spring framework.

callback function wikipedia example

Think of a method as giving a task to a coworker. A simple task might be the following:

 Solve these equations: x + 2 = y 2 * x = 3 * y 

Your coworker diligently does the math and gives you the following result:

 x = -6 y = -4 

But your coworker has a problem, he doesn't always understand notations, such as ^ , but he does understand them by their description. Such as exponent . Everytime he finds one of these you get back the following:

 I don't understand "^" 

This requires you to rewrite your entire instruction set again after explaining what the character means to your coworker, and he doesn't always remember in between questions. And he has difficulty remembering your tips as well, such as just ask me. He always follows your written directions as best he can however.

You think of a solution, you just add the following to all of your instructions:

 If you have any questions about symbols, call me at extension 1234 and I will tell you its name. 

Now whenever he has a problem he calls you and asks, rather than giving you a bad response and making the process restart.

Callbacks allows you to insert your own code into another block of code to be executed at another time, that modifies or adds to the behavior of that other block of code to suit your needs. You gain flexibility and customizability while being able to have more maintainable code.

Less hardcode = easier to maintain and change = less time = more business value = awesomeness.

For example, in javascript, using Underscore.js, you could find all even elements in an array like this:

 var evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); => [2, 4, 6] 

Example courtesy of Underscore.js: http://documentcloud.github.com/underscore/#filter

This of it in terms of downloading a webpage:

Your program runs on a cellphone and is requesting the webpage http://www.google.com . If you write your program synchronously, the function you write to download the data will be running continuously until all the data is download. This means your UI will not refresh and will basically appear frozen. If you write your program using callbacks, you request the data and say "execute this function when you've finished." This allows the UI to still allow user interaction while the file is downloading. Once the webpage has finished downloading, your result function (callback) is called and you can handle the data.

Basically, it allows you to request something and continue executing while waiting for the result. Once the result comes back to you via a callback function, you can pick up the operation where it left off.