How to explain callbacks in plain english? How are

2018-12-31 17:13发布

问题:

How to explain callbacks in plain English? How are they different from calling one function from another function taking some context from the calling function? How can their power be explained to a novice programmer?

回答1:

Often an application needs to execute different functions based upon its context/state. For this, we use a variable where we would store the information about the function to be called. ‪According to its need the application will set this variable with the information about function to be called and will call the function using the same variable.

In javascript, the example is below. Here we use method argument as a variable where we store information about function.

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]


回答2:

I am going to try to keep this dead simple. A \"callback\" is any function that is called by another function which takes the first function as a parameter. A lot of the time, a \"callback\" is a function that is called when something happens. That something can be called an \"event\" in programmer-speak.

Imagine this scenario: you are expecting a package in a couple of days. The package is a gift for your neighbor. Therefore, once you get the package, you want it brought over to the neighbors. You are out of town, and so you leave instructions for your spouse.

You could tell them to get the package and bring it to the neighbors. If your spouse was as stupid as a computer, they would sit at the door and wait for the package until it came (NOT DOING ANYTHING ELSE) and then once it came they would bring it over to the neighbors. But there\'s a better way. Tell your spouse that ONCE they receive the package, they should bring it over the neighbors. Then, they can go about life normally UNTIL they receive the package.

In our example, the receiving of the package is the \"event\" and the bringing it to the neighbors is the \"callback\". Your spouse \"runs\" your instructions to bring the package over only when the package arrives. Much better!

This kind of thinking is obvious in daily life, but computers don\'t have the same kind of common sense. Consider how programmers normally write to a file:

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

Here, we WAIT for the file to open, before we write to it. This \"blocks\" the flow of execution, and our program cannot do any of the other things it might need to do! What if we could do this instead:

# 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!

It turns out we do this with some languages and frameworks. It\'s pretty cool! Check out Node.js to get some real practice with this kind of thinking.



回答3:

How to explain callbacks in plain English?

In plain English, a callback function is like a Worker who \"calls back\" to his Manager when he has completed a Task.

How are they different from calling one function from another function taking some context from the calling function?

It is true that you are calling a function from another function, but the key is that the callback is treated like an Object, so you can change which Function to call based on the state of the system (like the Strategy Design Pattern).

How can their power be explained to a novice programmer?

The power of callbacks can easily be seen in AJAX-style websites which need to pull data from a server. Downloading the new data may take some time. Without callbacks, your entire User Interface would \"freeze up\" while downloading the new data, or you would need to refresh the entire page rather than just part of it. With a callback, you can insert a \"now loading\" image and replace it with the new data once it is loaded.

Some code without a 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)\');
}

With Callback:

Here is an example with a callback, using jQuery\'s getJSON:

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
}

With Closure:

Often the callback needs to access state from the calling function using a closure, which is like the Worker needing to get information from the Manager before he can complete his Task. To create the closure, you can inline the function so it sees the data in the calling context:

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

Usage:

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

Closure

Finally, here is a definition of closure from Douglas Crockford:

Functions can be defined inside of other functions. The inner function has access to the vars and parameters of the outer function. If a reference to an inner function survives (for example, as a callback function), the outer function\'s vars also survive.

See also:

  • http://javascript.crockford.com/survey.html
  • http://api.jquery.com/jQuery.when/
  • http://api.jquery.com/jQuery.getJSON/
  • http://github.com/josher19/jQuery-Parse


回答4:

I\'m stunned to see so many intelligent people failing to stress the reality that the word \"callback\" has come to be used in two inconsistent ways.

Both ways involve the customization of a function by passing additional functionality (a function definition, anonymous or named) to an existing function. ie.

customizableFunc(customFunctionality)

If the custom functionality is simply plugged into the code block, you have customized the function, like so.

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

Though this kind of injected functionality is often called a \"callback\", there is nothing contingent about it. A very obvious example is the forEach method in which a custom function is supplied as an argument to be applied to each element in an array to modify the array.

But this is fundamentally distinct from the use of \"callback\" functions for asynchronous programming, as in AJAX or node.js or simply in assigning functionality to user interaction events (like mouse clicks). In this case, the whole idea is to wait for a contingent event to occur before executing the custom functionality. This is obvious in the case of user interaction, but is also important in i/o (input/output) processes that can take time, like reading files from disk. This is where the term \"callback\" makes the most obvious sense. Once an i/o process is started (like asking for a file to be read from disk or a server to return data from an http request) an asynchronous program doesn\'t wait around for it to finish. It can go ahead with whatever tasks are scheduled next, and only respond with the custom functionality after it has been notified that the read file or http request is completed (or that it failed) and that the data is available to the custom functionality. It\'s like calling a business on the phone and leaving your \"callback\" number, so they can call you when someone is available to get back to you. That\'s better than hanging on the line for who knows how long and not being able to attend to other affairs.

Asynchronous use inherently involves some means of listening for the desired event (e.g, the completion of the i/o process) so that, when it occurs (and only when it occurs) the custom \"callback\" functionality is executed. In the obvious AJAX example, when the data actually arrives from the server, the \"callback\" function is triggered to use that data to modify the DOM and therefore redraw the browser window to that extent.

To recap. Some people use the word \"callback\" to refer to any kind of custom functionality that can be injected into an existing function as an argument. But, at least to me, the most appropriate use of the word is where the injected \"callback\" function is used asynchronously -- to be executed only upon the occurrence of an event that it is waiting to be notified of.



回答5:

In non-programmer terms, a callback is a fill-in-the-blank in a program.

A common item on many paper forms is \"Person to call in case of emergency\". There is a blank line there. You write in someone\'s name and phone number. If an emergency occurs, then that person gets called.

  • Everyone gets the same blank form, but
  • Everyone can write a different emergency contact number.

This is key. You do not change the form (the code, usually someone else\'s). However you can fill in missing pieces of information (your number).

Example 1:

Callbacks are used as customized methods, possibly for adding to/changing a program\'s behavior. For example, take some C code that performs a function, but does not know how to print output. All it can do is make a string. When it tries to figure out what to do with the string, it sees a blank line. But, the programmer gave you the blank to write your callback in!

In this example, you do not use a pencil to fill in a blank on a sheet of paper, you use the function set_print_callback(the_callback).

  • The blank variable in the module/code is the blank line,
  • set_print_callback is the pencil,
  • and the_callback is your information you are filling in.

You\'ve now filled in this blank line in the program. Whenever it needs to print output, it will look at that blank line, and follow the instructions there (i.e. call the function you put there.) Practically, this allows the possibility of printing to screen, to a log file, to a printer, over a network connection, or any combination thereof. You have filled in the blank with what you want to do.

Example 2:

When you get told you need to call an emergency number, you go and read what is written on the paper form, and then call the number you read. If that line is blank nothing will be done.

Gui programming works much the same way. When a button is clicked, the program needs to figure out what to do next. It goes and looks for the callback. This callback happens to be in a blank labeled \"Here\'s what you do when Button1 is clicked\"

Most IDEs will automatically fill in the blank for you (write the basic method) when you ask it to (e.g. button1_clicked). However that blank can have any method you darn well please. You could call the method run_computations or butter_the_biscuits as long as you put that callback\'s name in the proper blank. You could put \"555-555-1212\" in the emergency number blank. It doesn\'t make much sense, but it\'s permissible.


Final note: That blank line that you\'re filling in with the callback? It can be erased and re-written at will. (whether you should or not is another question, but that is a part of their power)



回答6:

Johny the programmer needs a stapler, so he goes down to the office supply department and ask for one, after filling the request form he can either stand there and wait for the clerk go look around the warehouse for the stapler (like a blocking function call) or go do something else meantime.

since this usually takes time, johny puts a note together with the request form asking them to call him when the stapler is ready for pickup, so meantime he can go do something else like napping on his desk.



回答7:

Always better to start with an example :).

Let\'s assume you have two modules A and B.

You want module A to be notified when some event/condition occurs in module B. However, module B has no idea about your module A. All it knows is an address to a particular function (of module A) through a function pointer that is provided to it by module A.

So all B has to do now, is \"callback\" into module A when a particular event/condition occurs by using the function pointer. A can do further processing inside the callback function.

*) A clear advantage here is that you are abstracting out everything about module A from module B. Module B does not have to care who/what module A is.



回答8:

Imagine you need a function that returns 10 squared so you write a function:

function tenSquared() {return 10*10;}

Later you need 9 squared so you write another function:

function nineSquared() {return 9*9;}

Eventually you will replace all of these with a generic function:

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

The exact same thinking applies for callbacks. You have a function that does something and when done calls doA:

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

Later you want the exact same function to call doB instead you could duplicate the whole function:

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

Or you could pass a callback function as a variable and only have to have the function once:

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

Then you just have to call compute(doA) and compute(doB).

Beyond simplifying code, it lets asynchronous code let you know it has completed by calling your arbitrary function on completion, similar to when you call someone on the phone and leave a callback number.



回答9:

You feel ill so you go to the doctor. He examines you and determines you need some medication. He prescribes some meds and calls the prescription into your local pharmacy. You go home. Later your pharmacy calls to tell you your prescription is ready. You go and pick it up.



回答10:

There\'s two points to explain, one is how a callback works (passing around a function that can be called without any knowledge of its context), the other what it\'s used for (handling events asynchronously).

The analogy of waiting for a parcel to arrive that has been used by other answers is a good one to explain both. In a computer program, you would tell the computer to expect a parcel. Ordinarily, it would now sit there and wait (and do nothing else) until the parcel arrives, possibly indefinitely if it never arrives. To humans, this sounds silly, but without further measures, this is totally natural to a computer.

Now the callback would be the bell at your front door. You provide the parcel service with a way to notify you of the parcel\'s arrival without them having to know where (even if) you are in the house, or how the bell works. (For instance, some \"bells\" actually dispatch a phone call.) Because you provided a \"callback function\" that can be \"called\" at any time, out of context, you can now stop sitting at the front porch and \"handle the event\" (of parcel arrival) whenever it\'s time.



回答11:

Imagine a friend is leaving your house, and you tell her \"Call me when you get home so that I know you arrived safely\"; that is (literally) a call back. That\'s what a callback function is, regardless of language. You want some procedure to pass control back to you when it has completed some task, so you give it a function to use to call back to you.

In Python, for example,

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

grabDBValue could be written to only grab a value from a database and then let you specify what to actually do with the value, so it accepts a function. You don\'t know when or if grabDBValue will return, but if/when it does, you know what you want it to do. Here, I pass in an anonymous function (or lambda) that sends the value to a GUI window. I could easily change the behavior of the program by doing this:

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

Callbacks work well in languages where functions are first class values, just like the usual integers, character strings, booleans, etc. In C, you can \"pass\" a function around by passing around a pointer to it and the caller can use that; in Java, the caller will ask for a static class of a certain type with a certain method name since there are no functions (\"methods,\" really) outside of classes; and in most other dynamic languages you can just pass a function with simple syntax.

Protip:

In languages with lexical scoping (like Scheme or Perl) you can pull a trick like this:

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 in this case will be 6 because the callback has access to the variables declared in the lexical environment where it was defined. Lexical scope and anonymous callbacks are a powerful combination warranting further study for the novice programmer.



回答12:

You have some code you want to run. Normally, when you call it you are then waiting for it to be finished before you carry on (which can cause your app to go grey/produce a spinning time for a cursor).

An alternative method is to run this code in parallel and carry on with your own work. But what if your original code needs to do different things depending on the response from the code it called? Well, in that case you can pass in the name/location of the code you want it to call when it\'s done. This is a \"call back\".

Normal code: Ask for Information->Process Information->Deal with results of Processing->Continue to do other things.

With callbacks: Ask for Information->Process Information->Continue to do other things. And at some later point->Deal with results of Processing.



回答13:

Without callback neither others special programming resources (like threading, and others), a program is exactly a sequence of instructions which are executed sequentially one after the other, and even with a kind of \"dynamic behavior\" determined by certain conditions, all possible scenarios shall be previously programmed.

So, If we need to provide a real dynamic behavior to a program we can use callback. With callback you can instructs by parameters, a program to call an another program providing some previously defined parameters and can expects some results (this is the contract or operation signature), so these results can be produced/processed by third-party program which wasn\'t previously known.

This technique is the foundation of polymorphism applied to programs, functions, objects and all others unities of code ran by computers.

The human world used as example to callback is nice explained when you are doing some job, lets suppose you are a painter (here you are the main program, that paints) and call your client sometimes to ask him to approve the result of your job, so, he decides if the picture is good (your client is the third-party program).

In the above example you are a painter and \"delegate\" to others the job to approve the result, the picture is the parameter, and each new client (the called-back \"function\") changes the result of your work deciding what he wants about the picture (the decision made by the clients are the returned result from the \"callback function\").

I hope this explanation can be useful.



回答14:

Let\'s pretend you were to give me a potentially long-running task: get the names of the first five unique people you come across. This might take days if I\'m in a sparsely populated area. You\'re not really interested in sitting on your hands while I\'m running around so you say, \"When you\'ve got the list, call me on my cell and read it back to me. Here\'s the number.\".

You\'ve given me a callback reference--a function that I\'m supposed to execute in order to hand off further processing.

In JavaScript it might look something like this:

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

This could probably be improved in lots of ways. E.g., you could provide a second callback: if it ends up taking longer than an hour, call the red phone and tell the person that answers that you\'ve timed out.



回答15:

Callbacks are most easily described in terms of the telephone system. A function call is analogous to calling someone on a telephone, asking her a question, getting an answer, and hanging up; adding a callback changes the analogy so that after asking her a question, you also give her your name and number so she can call you back with the answer. -- Paul Jakubik , \"Callback Implementations in C++\"



回答16:

A callback is a function that will be called by a second function. This second function doesn\'t know in advance what function it will call. So the identity of the callback function is stored somewhere, or passed to the second function as a parameter. This \"identity,\" depending on the programming language, might be the address of the callback, or some other sort of pointer, or it might be the name of the function. The principal is the same, we store or pass some information that unambiguously identifies the function.

When the time comes, the second function can call the callback, supplying parameters depending on the circumstances at that moment. It might even choose the callback from a set of possible callbacks. The programming language must provide some kind of syntax to allow the second function to call the callback, knowing its \"identity.\"

This mechanism has a great many possible uses. With callbacks, the designer of a function can let it be customized by having it call whatever callbacks are provided. For example, a sorting function might take a callback as a parameter, and this callback might be a function for comparing two elements to decide which one comes first.

By the way, depending on the programming language, the word \"function\" in the above discussion might be replaced by \"block,\" \"closure,\" \"lambda,\" etc.



回答17:

Usually we sent variables to functions . Suppose you have task where the variable needs to be processed before being given as an argument - you can use callback .

function1(var1, var2) is the usual way .

What if I want var2 to be processed and then sent as an argument? function1(var1, function2(var2))

This is one type of callback - where function2 executes some code and returns a variable back to the initial function .



回答18:

A metaphorical explanation:

I have a parcel I want delivered to a friend, and I also want to know when my friend receives it.

So I take the parcel to the post office and ask them to deliver it. If I want to know when my friend receives the parcel, I have two options:

(a) I can wait at the post office until it is delivered.

(b) I will get an email when it is delivered.

Option (b) is analogous to a callback.



回答19:

For teaching callbacks, you have to teach the pointer first. Once the students understand the idea of pointer to a variable, idea of callbacks will get easier. Assuming you are using C/C++, these steps can be followed.

  • First show your students how to use and manipulate variables using pointers alongside using the normal variable identifiers.
  • Then teach them there are things that can be done only with pointers(like passing a variable by reference).
  • Then tell them how executable code or functions are just like some other data(or variables) in the memory. So, functions also have addresses or pointers.
  • Then show them how functions can be called with function pointers and tell these are called callbacks.
  • Now, the question is, why all these hassle for calling some functions? What is the benefit? Like data pointers, function pointer aka callbacks has some advantages over using normal identifiers.
  • The first one is, function identifiers or function names cannot be used as normal data. I mean, you cannot make a data structure with functions(like an array or a linked list of functions). But with callbacks, you can make an array, a linked list or use them with other data like in dictionary of key-value pairs or trees, or any other things. This is a powerful benefit. And other benefits are actually child of this one.
  • The most common use of callbacks is seen in event driver programming. Where one or more functions are executed based on some incoming signal. With callbacks, a dictionary can be maintained to map signals with callbacks. Then the input signal resolution and execution of corresponding code become much easier.
  • The second use of callbacks coming in my mind is higher order functions. The functions which takes other functions as input arguments. And to send functions as arguments, we need callbacks. An example can be a function which take an array and a callback. Then it performs the callback on each of the item of the array and return the results in another array. If we pass the function a doubling callback, we get a doubled valued array. If we pass a squaring callback, we get squares. For square roots, just send appropriate callback. This cannot be done with normal functions.

There might many more things. Involve the students and they will discover. Hope this helps.



回答20:

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 i.e. 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.

Hope that helps!



回答21:

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.



回答22:

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 B I don\'t know which callback function should be called. At the time I call function B I also tell this function to call function A. That is all.



回答23:

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


回答24:

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.



回答25:

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.



回答26:

“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

  • List item

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

  • List item

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.



回答27:

[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



回答28:

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.



回答29:

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



回答30:

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.