如何用简单的英语解释回调?它们与从一个函数调用另一个函数从调用函数获取上下文有什么不同?如何向新手程序员解释它们的强大功能?


当前回答

简单明了:回调是你给另一个函数的函数,这样它就可以调用它。

通常在某个操作完成时调用它。由于在将回调函数交给其他函数之前创建了回调,因此可以使用调用站点的上下文信息初始化它。这就是为什么它被命名为call*back* -第一个函数从它被调用的地方回调到上下文。

其他回答

隐喻性的解释:

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

所以我把包裹带到邮局,让他们把它送到。如果我想知道我的朋友什么时候收到包裹,我有两个选择:

我可以在邮局等邮件送到。

(b)邮件送达后我会收到电子邮件。

选项(b)类似于回调。

在PHP中,它是这样的:

<?php

function string($string, $callback) {
     $results = array(
        'upper' => strtoupper($string),
        'lower' => strtolower($string),
        );

    if(is_callable($callback)) {
        call_user_func($callback, $results);
    }
}

string('Alex', function($name) {
    echo $name['lower'];
});

当我们有两个函数,函数a和函数b,如果函数a依赖于函数b。

然后我们调用函数b作为回调函数。这在Spring框架中被广泛使用。

让我们假设您要给我一个可能长期运行的任务:获取您遇到的前五个独特的人的名字。如果我在人口稀少的地区,这可能需要几天的时间。你真的不想在我忙来忙去的时候袖手旁观,所以你说:“你拿到名单后,打我手机给我读一遍。这是号码。”

您已经给了我一个回调引用——一个我应该执行以传递进一步处理的函数。

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

这可能有很多方面可以改进。例如,你可以提供第二次回拨:如果最终超过一个小时,打电话给红色电话,告诉接听电话的人你超时了。

什么是回调函数?

对第一个问题的简单回答是,回调函数是通过函数指针调用的函数。如果你将一个函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用它所指向的函数时,就被称为回调。

回调函数很难跟踪,但有时它非常有用。尤其是在设计库的时候。回调函数就像让你的用户给你一个函数名,你会在一定条件下调用这个函数。

例如,您编写了一个回调计时器。它允许您指定持续时间和调用什么函数,函数将相应地被回调。“每10秒运行myfunction() 5次”

或者,您可以创建一个函数目录,传递一个函数名列表,并要求库进行相应的回调。"如果成功,回调成功(),如果失败,回调失败()。"

让我们看一个简单的函数指针的例子

void cbfunc()
{
     printf("called");
}

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

如何传递参数回调函数?

注意到实现回调的函数指针接受void *,这表明它可以接受任何类型的变量,包括结构。因此,您可以通过结构传递多个参数。

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;
     m.a=10;
     strcpy(m.b,"123");       
     callback = (void*)cbfunc;    /* point to callback function */
     callback(&m);                /* perform callback and pass in the param */
     return 0;   
}