Create delay in ActionScript 3 function - actionscript-3

I have a function in Adobe Flex 4 (ActionScript 3) that accepts an object and returns an ArrayCollection...
If a certain global variable is set to true, I want the function to delay itself for 3 seconds before running. Otherwise I want the function to run as normal.
The problem is, if I use a Timer, that timer calls a separate function, and that function cannot return anything to my calling function, nor can the function it calls accept any parameters, so it's not like I can call my own function recursively after the TimerComplete event fires... And a recursive call wouldn't work anyway, because it would return the ArrayCollection to the timer-result function, not to the original calling function...
I need a delay within the function, not a delay that causes me to go outside that function. But I cannot figure out how to do it.
Something like this is what I need to do:
private function createArrayCollection(myObject:Object):ArrayCollection {
var myArrayCollection:ArrayCollection = new ArrayCollection();
if (globalWaitBoolean) {
//delay here for 3 seconds, somehow
}
//Here I do the stuff that uses the info in myObject to figure out what to
//put into the ArrayCollection I want to return
return (myArrayCollection);
}
So... Any ideas on how to accomplish this without calling an external Timer function that cannot return an object back to my original function?
Thanks,

The way you want it you will have your whole application to lag for 3 seconds, unresponsive to any user input and external events. But it is possible, sure:
import flash.utils.getTimer;
private function createArrayCollection(myObject:Object):ArrayCollection
{
var myArrayCollection:ArrayCollection = new ArrayCollection;
if (globalWaitBoolean)
{
var waitUntil:int = getTimer() + 3000;
// Method getTimer() returns time in ms passed since app start.
// So you just have to wait until it is greater than appointed time.
while (getTimer() < waitUntil)
{
// Do nothing.
}
}
return (myArrayCollection);
}
Still, if you want to do it in a correct way of doing it:
import flash.utils.setTimeout;
private function callerMethod():void
{
// Blah blah blah.
// ...
// Finally.
createArrayCollection(sourceData, asyncResult);
}
private function createArrayCollection(myObject:Object, handler:Function):void
{
var result:ArrayCollection = new ArrayCollection;
if (globalWaitBoolean) setTimeout(handler, 3000, result);
else handler(result);
}
private function asyncResult(source:ArrayCollection):void
{
// The rest of your processing code.
}

Normal (synchronous) code flow would not return until the value is prepared, so should you desire to actually wait for 3 seconds while not allowing your app to do anything, use getTimer() approach from #Organis's answer. If you'll go for an asynchronus result, you'll need to face and overcome some more problems.
First, when do you expect your returned ArrayCollection to actually arrive. Speaking of code design, asynchronous code requires a whole lot of assumptions, thread safety etc etc, and even while AS3/Flash does not have true multithreading unless you count Workers, the code flow with events is not as obvious. So, whoever called your createArrayCollection() MUST NOT expect value returned from it right away. So, speaking about your direct question, NO, you can't avoid timers of some sort if you desire a responsive application. But you can use them with an approach that would involve an indirectly returned result.
Second, whether there might be concurring requests for more array collections from objects if your app would require these - you have to prepare for any kind of interference that might be caused by this. Say your function is triggered by a button click - what if that button would get clicked more than once in 3 seconds?
Third, actual route to processing code is not direct with asynchronous return. You need either a callback, an event handler (which is essentially a semi-native callback), a code that periodically checks for value presence (enter frame handler, etc) or a similar trick to gather the value that's returned asynchronously, and then transfer it to any relevant code that would process it further. Therefore, you would need to design an interface capable of receiving complex data (source object forward, array collection backward) and then carefully test it against all the possible cases and flaws.
An example of implementing all that is very long, I'll try to outline it somehow. Ler's assume you have a sort of "server" class that accepts requests for data and processes it synchronously (no wait) or asynchronously (wait). It accepts a source object of type "T" and provides a newly created object of type ArrayCollection, supplied as a parameter to whatever callback function sent to it. Also it accepts a delay (a simple way to show sync/async return would be a boolean, but why not getting an int?) as a parameter, and guarantees (to the extent of event model limitations) that after this delay the callback will be called ASAP. The architecture will then look like this:
class Processor {
Dictionary requests; // here all the requests that are delayed will be stored
public function dpr(source:T,callback:Function,delay:int=0):void{...}
// creates requests and stores them
private function syncProcess(source:T):ArrayCollection {...}
// whatever routine you want to get variably delayed
private function processTimeout(e:Event=null):void {...}
// processes events from "setTimeout()" and calls callbacks
}
Note that asynchronous approach forced to create three more entities than a synchronous one. First is the request holding structure (the dictionary here), second is timeout event handler, third is whatever callback you'll desire to get called when the data is ready. The code flow would go like this:
Synchronous call would result in the callback directly called from within the class: request->processTimeout->syncProcess()->callback. Asynchronous call will have the callback called from within Timer::timerComplete event handler via setTimeout called within request, with data that originally came from request stored in requests.

You could use an embedded/inline function:
private function createArrayCollection(myObject:Object):ArrayCollection {
var myArrayCollection:ArrayCollection = new ArrayCollection();
if (globalWaitBoolean) {
var milliseconds:int = 3000;
//delay here for 3 seconds
setTimeout(function()
{
//Here I do the stuff that uses the info in myObject to figure out what to
//put into the ArrayCollection I want to return
return (myArrayCollection);
},
milliseconds);
}
else
{
//Here I do the stuff that uses the info in myObject to figure out what to
//put into the ArrayCollection I want to return
return (myArrayCollection);
}
}
The inner function will have access to all local vars of the outer function.

Related

Timer, SetInterval, Alarm, etc

Help turning multiple functions into a a few functions.
var myNumberOne = 10;
var myNumberTwo = 100;
function one would create a timer or interval that fire 2 times every second, Traceing the word "food", It would when finished, "myNumberOne += 10" making myNumberOne = 20;
function two would create a timer or interval that fire 5 times every half-second, Traceing the word "ben", It would when finished, "myNumberTwo += 50" making myNumberTwo = 250;
For two functions this is fine, but if I have 100s of possible combinations, I cannot think on this should be done, without intervals , timers, functions etc... interfering with each-other, and passing arguments through time.
Thanks for any help.
for clarification: I waant to call a function like this
setTimeFunction("myTimeOne", myNumberOne, 2,1000,10, "ben");
setTimeFunction("myTimeTwo", myNumberTwo, 5,500,50,"food");
Well, first, you need to compose a generic method that would perform a number of similar actions. Tracing is easy, but you cannot pass a variable to change directly because you'll pass a value, not a reference to variable. In order to do as you want you need to pass it as a pair "container object" and "variable name" to use the square bracket notation.
function myownDothings(target:Object, varname:String, adiff:int, totrace:String):void
{
// Use square bracket notation to change the targeted variable.
target[varname] += adiff;
// Trace the given argument.
trace(totrace);
}
Ok, now the simple complicated part. There's a setTimeout(...) function that calls the given method many times with a given timeout, but it's official documentation officially advises the use of Timer class.
I hope you know how to work with classes, because the thing you want calls for OOP and fitting it into the frame scripts will result in something ugly. So, you need to compose a class that remembers function to call, timeout settings and a bunch of arguments as well.
package
{
import flash.utils.Timer;
import flash.events.TimerEvent;
public class Ticker
{
// You need to keep the references to the things you use,
// or else Garbage Collector might think you don't need it.
static private var list:Array = new Array;
// Instead of static method you can use the "constructor" way,
// but I find it more stylish and it's one more thing for
// you to google and learn of, which I totally approve.
// The ... construction allows to pass a random number
// of arguments (after fixed arguments) as an Array.
static public function create(handler:Function, timeout:int, ...args:Array):void
{
var aTicker:Ticker;
// Brackets () are not mandatory with the "new" operator
// if there are no mandatory constructor arguments.
aTicker = new Ticker;
// Store all the necessary data in the new instance. That's the
// point of OOP scripting here: you want to make 100 different
// tickers and you need each of them to keep some custom data.
aTicker.timeout = timeout;
aTicker.handler = handler;
aTicker.args = args;
// Finally, run the ticker.
aTicker.start();
// Store the created instance into the keeper list
// to prevent Garbage Collector from destroying it.
list.push(aTicker);
}
// Again, fear the Garbage Collector.
private var clock:Timer;
// Keep in mind that timeout is not exactly accurate
// as it aligns to the SWF's frame rate. Setting it up to call
// more times a second than FPS will pose to be a meaningless act.
private var timeout:int;
// The reference to the method to call.
private var handler:Function;
// The list of arguments to pass to the method above.
private var args:Array;
// This method is called from the "create" method
// to finalize things and start ticking.
private function start():void
{
// Create a Timer instance with a given timeout.
clock = new Timer(timeout);
// Subscribe the listener to the Timer.
clock.addEventListener(TimerEvent.TIMER, onTick);
// Start the Timer.
clock.start();
}
// The Timer instance will trigger this method
// (approximately) every given timeout of milliseconds.
private function onTick(e:TimerEvent):void
{
// Now the idea is to call the given method
// passing the list of given arguments to it.
// Normally you don't need to pass the "this" object
// to a method unless you use unnamed unbound closures.
// (which I personally consider a heresy and don't recommend to use)
// So you just pass "null" as the first argument and everything is fine.
handler.apply(null, args);
}
}
}
Now, the usage. It's where all the horrors above finally shine.
import Ticker;
var myNumberOne = 10;
var myNumberTwo = 100;
// Fire 2 times every second, increase "myNumberOne" by 10, trace the word "ben".
// So, 2 times a second it will call: myownDothings(this, "myNumberOne", 10, "ben");
Ticker.create(myownDothings, 1000 / 2, this, "myNumberOne", 10, "ben");
// Fire 5 times every half a second, increase "myNumberTwo" by 50, trace the word "food".
// So, 10 times a second it will call: myownDothings(this, "myNumberTwo", 50, "food");
Ticker.create(myownDothings, 500 / 5, this, "myNumberTwo", 50, "food");

AS3: Returning value from another function after event happened

Basically I want to check if a user exists in a database using AMF (and that works great!). But then I want to return the boolean value to another function (in another class) that originally called the "checkUserExistance" function. But, since the database connection isn't immidiate, this function will always return a false value (even if "result" is true). So I would like to have the return-line inside the "onUserChecked"-function but that of course gives me an error. I thought I could create an eventListener, but then, the "return userExists"-line would also have to be inside another function, which doesnät work(?)... What can I do?
public function checkUserExistance(username:String) {
var responderBOOLEAN:Responder = new Responder(onUserChecked, onFault)
var userExists:Boolean = false;
connection.connect(gateway);
connection.call("User.checkUser", responderBOOLEAN, username);
connection.close();
function onUserChecked(result:Boolean):void {
userExists = result;
}
return userExists;
}
I'm sorry but you are trying to force an Asynchronous call to a Synchronous one and this is WRONG.
See here
You should learn how to handle events in the correct way.
What can i suggest you that helped me a lot is this
The only true answer here is to save userExists as a member variable, and dispatch event when the server returns you a response. The client side of the things should be similar to:
// add listener, ServerEvent is a custom event (see below)
server.addEventListener(ServerEvent.CHECK_RESPONSE, onCheckResponse);
server.checkUserExistance('username'); // start the query
function onCheckResponse(e:ServerEvent):void {
if (e.userExists) {
}
}
// inside server class
function onUserChecked(result:Boolean):void {
userExists = true;
dispatchEvent(new ServerEvent(ServerEvent.CHECK_RESPONSE, userExists));
}
/* ServerEvent is a custom class that extens Event
Such classes are used so you can pass special properties in them
via constructor (pass data, store it into member variable)
and through getter for that variable.
If you don't like it, simply add/dispatch Event.COMPLETE
and use public property to get userExists from server
*/

Calling certain functions whitout having the right arguments

I have two function on my AS3 program, one fires when the width and height changes:
stage.addEventListener(Event.RESIZE, resizeListener);
function resizeListener (e:Event):void {
//some commands
}
And the second one fires one a number of milliseconds pass:
var myTimer:Timer = new Timer(clockUpdate, 0);
myTimer.addEventListener(TimerEvent.TIMER, updateData);
myTimer.start();
function updateData(e:TimerEvent):void {
trace("AUTOUPDATE");
trace(e);
}
I need to fires those function also manually, lets say when the user press a button, but i don't know what parameters i have to send them when they are called manually.
I tried just resizeListener() and updateData() but of course it fails asking me for the parameter.
You can make parameters in a function optional by providing a default value. This is an example by taking your two functions above and making the event parameters optional:
function resizeListener(e:Event = null):void {
//some commands
}
and
function updateData(e:TimerEvent = null):void {
trace("AUTOUPDATE");
trace(e);
}
Calling, for example, resizeListener() will now execute the function and the value of e will default to null.
Making the Event parameter optional, resizeListener(e:Event=null), as in walkietokyo's answer, is a perfectly valid and often convenient solution. Another alternative is to put the stuff you want to be able to do without the event being triggered in a separate function, that can be called by the event handler and from anywhere else.
So assuming for example that what you want to do on resize is to rearrange the layout, and you also want to do that same layout setup at initialization, or at the click of a button, or anytime really, you could do something like this:
stage.addEventListener(Event.RESIZE, resizeListener);
function resizeListener(e:Event):void {
rearrangeLayout();
}
function rearrangeLayout():void {
// The actual rearrangement goes here, instead of in resizeListener. This can be called from anywhere.
}
Which way to do it is probably a matter of taste or can vary from case to case, really, both works fine.
A benefit of separating things in an event handler and another function is that there will not arise a situation where you would have to check if the e:Event parameter is null or not. In other words, you would have code that is dependent on the Event, if any, in the event handler, and code that is independent of the Event in a more general function (not an event handler).
So in a more general and schematic case, the structure would be something like this:
addEventListener(Event.SOME_EVENT, eventListener);
function eventListener(e:Event):void {
// Code that needs the Event parameter goes here (if any).
// Call other function(s), for the stuff that needs to be done when the event happens.
otherFunction();
}
function otherFunction():void {
// Stuff that is not dependent on the Event object goes here, an can be called from anywhere.
}

Clearing eventListeners on a FileReference object

I have a strange issue! I am trying to remove an event listener on a FileReference object by calling a function, but it seems not to be removed, and I do not understand why.
Here is the code:
private function clearFileUploadListeners(file:FileReference, index:String):void {
var dispatchEvent:Function = function(event:Event):void {
dispatch(event.type, event, index);
};
file.removeEventListener(Event.COMPLETE, dispatchEvent);
var bool:Boolean = file.hasEventListener(Event.COMPLETE);
if (bool)
trace("ERROR");
}
When I run this code, the trace actually happens. I don't understand why this boolean returns true, when I just tried to remove the eventListener just above! I guess I am probably doing something really stupid because it seems like a strange error.
I hope someone can please help me on this issue.
EDIT:
I believe it has to do with the fact that the dispatchEvent function is defined inside another function when I add the listener:
private function upload(file:FileReference, index:String):void {
var dispatchEvent:Function = function(event:Event):void {
dispatch(event.type, event, index);
};
file.addEventListener(Event.COMPLETE, dispatchEvent);
}
The problem is that I need to access this "index" variable from the listener, and I can't set it as a global variable as each file has it's own index and it's a burden if I have to extend each event class to keep track of the index (Event, ProgressEvent, ..). I hope someone can please help me on this.
EDIT2:
I actually found a temporary solution, I am not sure if it is the best! I put my removeListener method actually inside the upload method, but made it a variable. As AS3 allows dynamic object, I attached this method to one of my object, and so I just call the reference to the method when necessary. The event is actually removed. Is this a good solution please?
Thank you very much,
Rudy
You're right, it has to do with the fact that you're defining a function inside another function, then using it to handle events.
Each time the function upload is called, it creates a new closure, and assigns a reference to it to the dispatchEvent variable, which is then passed to the addEventListener class. So each time upload is called, it is using a new, different closure in the call to addEventListener. Similarly, in the clearFileUploadListeners function, a new closure is being created on each call (which happens to have the same code each time, but isn't the same function object). The call to removeEventListener does nothing if the given callback has not been added as an event listener for the given event, which is the case here.
To solve your problem, you need to store a reference to the closure that you pass to the addEventListener function. This way, you can get a reference to the same closure that was added when you need to remove it later in clearFileUploadListeners.
You can try something along the lines of the following code (untested):
import flash.utils.Dictionary;
var callbackRegistry:* = new Dictionary();
private function upload(file:FileReference, index:String):void {
var dispatchEvent:Function = generateFileUploadCompleteCallback();
callbackRegistry[file] = dispatchEvent;
file.addEventListener(Event.COMPLETE, dispatchEvent);
}
private function clearFileUploadListeners(file:FileReference, index:String):void {
var dispatchEvent:Function = callbackRegistry[file];
callbackRegistry[file] = null;
file.removeEventListener(Event.COMPLETE, dispatchEvent);
var bool:Boolean = file.hasEventListener(Event.COMPLETE);
if (bool)
trace("ERROR");
else
trace("YAY, ALL OK!");
}
private function generateFileUploadCompleteCallback(index:String):Function {
return function(event:Event):void {
dispatch(event.type, event, index);
};
}
Two other things to note on this subject.
If you must utilize a native Event directly then you should pretty much always make sure and use these last three optional params :
myObject.addEventListener( Event.COMPLETE, myFunction, false, 0, true );
Check Grant Skinner's post on the subject here :
http://gskinner.com/blog/archives/2006/07/as3_weakly_refe.html
And the very best practice of all is to ALWAYS (seriously always) use Robert Penner's Signals (instead of custom events) and his NativeSignals (to wrap needed native Flash events).
Five times faster than Flash's native events.
Always safe with weak references.
Any number of typed payload(s) in each Signal.
Get the SWC here :
https://github.com/robertpenner/as3-signals
Signals were designed to solve the very problem you are having.
Imagine instead of creating an array and managing that to remove all listeners if you could just call :
signalBtnClicked.removeAll();
or
signalBtnClicked.addOnce( function( e : MouseEvent ) : void { /* do stuff */ } );
Knowing that the closure you just created will immediately be dereferenced once it is called and happily go night night when the GC makes its rounds.

What is a callback function?

What is a callback function?
Developers are often confused by what a callback is because of the name of the damned thing.
A callback function is a function which is:
accessible by another function, and
is invoked after the first function if that first function completes
A nice way of imagining how a callback function works is that it is a function that is "called at the back" of the function it is passed into.
Maybe a better name would be a "call after" function.
This construct is very useful for asynchronous behaviour where we want an activity to take place whenever a previous event completes.
Pseudocode:
// 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);
}
Result if you called event():
The number you provided is: 6
I have finished printing numbers.
The order of the output here is important. Since callback functions are called afterwards, "I have finished printing numbers" is printed last, not first.
Callbacks are so-called due to their usage with pointer languages. If you don't use one of those, don't labour over the name 'callback'. Just understand that it is just a name to describe a method that's supplied as an argument to another method, such that when the parent method is called (whatever condition, such as a button click, a timer tick etc) and its method body completes, the callback function is then invoked.
Some languages support constructs where multiple callback function arguments are supported, and are called based on how the parent function completes (i.e. one callback is called in the event that the parent function completes successfully, another is called in the event that the parent function throws a specific error, etc).
Opaque Definition
A callback function is a function you provide to another piece of code, allowing it to be called by that code.
Contrived example
Why would you want to do this? Let's say there is a service you need to invoke. If the service returns immediately, you just:
Call it
Wait for the result
Continue once the result comes in
For example, suppose the service were the factorial function. When you want the value of 5!, you would invoke factorial(5), and the following steps would occur:
Your current execution location is saved (on the stack, but that's not important)
Execution is handed over to factorial
When factorial completes, it puts the result somewhere you can get to it
Execution comes back to where it was in [1]
Now suppose factorial took a really long time, because you're giving it huge numbers and it needs to run on some supercomputing cluster somwhere. Let's say you expect it to take 5 minutes to return your result. You could:
Keep your design and run your program at night when you're asleep, so that you're not staring at the screen half the time
Design your program to do other things while factorial is doing its thing
If you choose the second option, then callbacks might work for you.
End-to-end design
In order to exploit a callback pattern, what you want is to be able to call factorial in the following way:
factorial(really_big_number, what_to_do_with_the_result)
The second parameter, what_to_do_with_the_result, is a function you send along to factorial, in the hope that factorial will call it on its result before returning.
Yes, this means that factorial needs to have been written to support callbacks.
Now suppose that you want to be able to pass a parameter to your callback. Now you can't, because you're not going to be calling it, factorial is. So factorial needs to be written to allow you to pass your parameters in, and it will just hand them over to your callback when it invokes it. It might look like this:
factorial (number, callback, params)
{
result = number! // i can make up operators in my pseudocode
callback (result, params)
}
Now that factorial allows this pattern, your callback might look like this:
logIt (number, logger)
{
logger.log(number)
}
and your call to factorial would be
factorial(42, logIt, logger)
What if you want to return something from logIt? Well, you can't, because factorial isn't paying attention to it.
Well, why can't factorial just return what your callback returns?
Making it non-blocking
Since execution is meant to be handed over to the callback when factorial is finished, it really shouldn't return anything to its caller. And ideally, it would somehow launch its work in another thread / process / machine and return immediately so that you can continue, maybe something like this:
factorial(param_1, param_2, ...)
{
new factorial_worker_task(param_1, param_2, ...);
return;
}
This is now an "asynchronous call", meaning that when you call it, it returns immediately but hasn't really done its job yet. So you do need mechanisms to check on it, and to obtain its result when its finished, and your program has gotten more complex in the process.
And by the way, using this pattern the factorial_worker_task can launch your callback asynchronously and return immediately.
So what do you do?
The answer is to stay within the callback pattern. Whenever you want to write
a = f()
g(a)
and f is to be called asynchronously, you will instead write
f(g)
where g is passed as a callback.
This fundamentally changes the flow-topology of your program, and takes some getting used to.
Your programming language could help you a lot by giving you a way to create functions on-the-fly. In the code immediately above, the function g might be as small as print (2*a+1). If your language requires that you define this as a separate function, with an entirely unnecessary name and signature, then your life is going to get unpleasant if you use this pattern a lot.
If, on the other hand, you language allows you to create lambdas, then you are in much better shape. You will then end up writing something like
f( func(a) { print(2*a+1); })
which is so much nicer.
How to pass the callback
How would you pass the callback function to factorial? Well, you could do it in a number of ways.
If the called function is running in the same process, you could pass a function pointer
Or maybe you want to maintain a dictionary of fn name --> fn ptr in your program, in which case you could pass the name
Maybe your language allows you to define the function in-place, possible as a lambda! Internally it is creating some kind of object and passing a pointer, but you don't have to worry about that.
Perhaps the function you are calling is running on an entirely separate machine, and you are calling it using a network protocol like HTTP. You could expose your callback as an HTTP-callable function, and pass its URL.
You get the idea.
The recent rise of callbacks
In this web era we have entered, the services we invoke are often over the network. We often do not have any control over those services i.e. we didn't write them, we don't maintain them, we can't ensure they're up or how they're performing.
But we can't expect our programs to block while we're waiting for these services to respond. Being aware of this, the service providers often design APIs using the callback pattern.
JavaScript supports callbacks very nicely e.g. with lambdas and closures. And there is a lot of activity in the JavaScript world, both on the browser as well as on the server. There are even JavaScript platforms being developed for mobile.
As we move forward, more and more of us will be writing asynchronous code, for which this understanding will be essential.
The Callback page on Wikipedia explains it very well:
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.
A layman response would be that it is a function that is not called by you but rather by the user or by the browser after a certain event has happened or after some code has been processed.
Simple Explanation by Analogy
Everyday, I get to work. The boss tells me:
Oh, and when you're done with that, I have an extra task for you:
Great. He hands me a note with a task on it - this task is a call back function. It could be anything:
ben.doWork( and_when_finished_wash_my_car)
Tomorrow it could be:
ben.doWork( and_tell_me_how_great_i_am)
The key point is that the call back must be done AFTER I finish work....and that's it!
Now that you understand the concept (hopefully), you would do well to read the code contained in other answers.
A callback function is one that should be called when a certain condition is met. Instead of being called immediately, the callback function is called at a certain point in the future.
Typically it is used when a task is being started that will finish asynchronously (ie will finish some time after the calling function has returned).
For example, a function to request a webpage might require its caller to provide a callback function that will be called when the webpage has finished downloading.
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++"
I believe this "callback" jargon has been mistakenly used in a lot of places. My definition would be something like:
A callback function is a function that you pass to someone and let
them call it at some point of time.
I think people just read the first sentence of the wiki definition:
a callback is a reference to executable code, or a piece of
executable code, that is passed as an argument to other code.
I've been working with lots of APIs, see various of bad examples. Many people tend to name a function pointer (a reference to executable code) or anonymous functions(a piece of executable code) "callback", if they are just functions why do you need another name for this?
Actually only the second sentence in wiki definition reveals the differences between a callback function and a normal function:
This allows a lower-level software layer to call a subroutine (or
function) defined in a higher-level layer.
so the difference is who you are going to pass the function and how your passed in function is going to be called. If you just define a function and pass it to another function and called it directly in that function body, don't call it a callback. The definition says your passed in function is gonna be called by "lower-level" function.
I hope people can stop using this word in ambiguous context, it can't help people to understand better only worse.
Call back vs Callback Function
A Callback is a function that is to be executed after another function has finished executing — hence the name ‘call back’.
What is a Callback Function?
Functions which takes Funs(i.e. functional objects) as arguments, or which return Funs are called higher order functions.
Any function that is passed as an argument is called a callback function.
a callback function is a function that is passed to another function (let's call this other function otherFunction) as a parameter, and the callback function is called (or executed) inside the 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
In SOA, callback allows the Plugin Modules to access services from the container/environment.
Source
This makes callbacks sound like return statements at the end of methods.
I'm not sure that's what they are.
I think Callbacks are actually a call to a function, as a consequence of another function being invoked and completing.
I also think Callbacks are meant to address the originating invocation, in a kind of "hey! that thing you asked for? I've done it - just thought I would let you know - back over to you".
A callback function is a function you specify to an existing function/method, to be invoked when an action is completed, requires additional processing, etc.
In Javascript, or more specifically jQuery, for example, you can specify a callback argument to be called when an animation has finished.
In PHP, the preg_replace_callback() function allows you to provide a function that will be called when the regular expression is matched, passing the string(s) matched as arguments.
Call After would be a better name than the stupid name, callback. When or if condition gets met within a function, call another function, the Call After function, the one received as argument.
Rather than hard-code an inner function within a function, one writes a function to accept an already-written Call After function as argument. The Call After might get called based on state changes detected by code in the function receiving the argument.
look at the image :)
Main program calls library function (which might be system level function also) with callback function name. This callback function might be implemented in multiple way. The main program choose one callback as per requirement.
Finally, the library function calls the callback function during execution.
The simple answer to this 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
Assume we have a function sort(int *arraytobesorted,void (*algorithmchosen)(void)) where it can accept a function pointer as its argument which can be used at some point in sort()'s implementation . Then , here the code that is being addressed by the function pointer algorithmchosen is called as callback function .
And see the advantage is that we can choose any algorithm like:
1. algorithmchosen = bubblesort
2. algorithmchosen = heapsort
3. algorithmchosen = mergesort ...
Which were, say,have been implemented with the prototype:
1. `void bubblesort(void)`
2. `void heapsort(void)`
3. `void mergesort(void)` ...
This is a concept used in achieving Polymorphism in Object Oriented Programming
“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.
A callback is an idea of passing a function as a parameter to another function and have this one invoked once the process has completed.
If you get the concept of callback through awesome answers above, I recommend you should learn the background of its idea.
"What made them(Computer-Scientists) develop callback?"
You might learn a problem, which is blocking.(especially blocking UI)
And callback is not the only solution to it.
There are a lot of other solutions(ex: Thread, Futures, Promises...).
A callback function is a function you pass (as a reference or a pointer) to a certain function or object.
This function or object will call this function back any time later, possibly multiple times, for any kind of purpose :
notifying the end of a task
requesting comparison between two item (like in c qsort())
reporting progress of a process
notifying events
delegating the instanciation of an object
delegating the painting of an area
...
So describing a callback as a function being called at the end of another function or task is overly simplifying (even if it's a common use case).
One important usage area is that you register one of your function as a handle (i.e. a callback) and then send a message / call some function to do some work or processing. Now after the processing is done, the called function would call our registered function (i.e. now call back is done), thus indicating us processing is done. This wikipedia link explains quite well graphically.
A callback function, also known as a higher-order function, is a function that is passed to another function as a parameter, and the callback function is called (or executed) inside the parent function.
$("#button_1").click(function() {
alert("button 1 Clicked");
});
Here we have pass a function as a parameter to the click method. And the click method will call (or execute) the callback function we passed to it.
Callback Function
A function which passed to another function as an argument.
function test_function(){
alert("Hello world");
}
setTimeout(test_function, 2000);
Note: In above example test_function used as an argument for setTimeout function.
I'm 13 years late to the game on this answer but after learning it myself I thought I'd drop another answer in here in case anyone is baffled like I was.
The other answers sum up the crux of the question "What is a callback?"
It's just a function that calls another function when something is completed.
What got me was the examples, "You did this now do that."
Like WHY would I use it like that when I can just call a method or a function myself?
So here's a quick, real world example that hopefully makes it "click" for someone.
Ultra pseudocode
First the core issue you'll run into....
Multithreaded Method(Some arguments)
{
Do fancy multithreaded stuff....
}
Main()
{
Some stuff I wanna do = some tasks
Multhreaded Method(Some stuff I wanna do)
}
If you run that without any callback your program will look like it just exits.
Because the "Fancy multithreaded stuff" is running on another process.
So you scratch your head and think "Well hell, How do I know when it's done??"
BOOM... CALLBACK
IsItDone = false
Callback()
{
print("Hey, I'm done")
IsItDone = true
}
Multithreaded Method(Some arguments, Function callback)
{
Do fancy multithreaded stuff....
}
Main()
{
Some stuff I wanna do = some tasks
Multhreaded Method(Some stuff I wanna do,Callback)
while(!IsItDone)
Wait a bit
}
This is 100% not the best way to implement it, I just wanted to give a clear example.
So this isn't the bare "What is a callback?"
It's "What is a callback, and what does it do that benefits me???"